mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-26 12:14:56 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a86bc0af2 | ||
|
|
bc9f6ba0b0 | ||
|
|
9e16a0ae42 | ||
|
|
9ccbb49aef | ||
|
|
d59f84fbbc | ||
|
|
4bbb5008b1 | ||
|
|
49ce25511e | ||
|
|
985276665d | ||
|
|
91f553c45f | ||
|
|
38ede8ec58 | ||
|
|
997f6543ce | ||
|
|
b50081a83b | ||
|
|
34f512d244 | ||
|
|
eb5752f41b | ||
|
|
ef8e7419fa | ||
|
|
cfcdd15b89 | ||
|
|
b26debaebc | ||
|
|
6deb061b12 | ||
|
|
4c6745670c | ||
|
|
01c662b7de | ||
|
|
179fe652c2 | ||
|
|
394bc3260d | ||
|
|
ce1a70e2dc | ||
|
|
99022896f6 | ||
|
|
446b400667 | ||
|
|
7d53c21efe | ||
|
|
b78efbac36 | ||
|
|
9be9dcec46 | ||
|
|
3766ab802b | ||
|
|
b9141925a3 | ||
|
|
ed79fe86aa | ||
|
|
2f0b0955a9 | ||
|
|
2f8e15a900 | ||
|
|
b8b3a5c305 | ||
|
|
e7ea421c54 | ||
|
|
8de9699390 | ||
|
|
bf592a22ae | ||
|
|
8d4a619a15 | ||
|
|
1a3588624d | ||
|
|
74b3fd2efc | ||
|
|
091356ed59 | ||
|
|
fc0e1ee311 | ||
|
|
8dbfcbff58 | ||
|
|
317591bc8a | ||
|
|
f71b3b91c0 | ||
|
|
9e255bcbce | ||
|
|
8af319b953 | ||
|
|
f90fd9cec4 | ||
|
|
d386b1c12d | ||
|
|
81551ec50d | ||
|
|
8fafcf6eaa | ||
|
|
f0df6c61c9 | ||
|
|
6cf36b5771 | ||
|
|
54799187e9 | ||
|
|
6d0320be06 | ||
|
|
317a1527ad | ||
|
|
490eb0f57f | ||
|
|
f95283e341 | ||
|
|
837da0e458 | ||
|
|
8ce82a100e | ||
|
|
9ece98c101 | ||
|
|
6a83147b33 | ||
|
|
90e4228e1d | ||
|
|
553aeeef77 | ||
|
|
6147e865f8 | ||
|
|
7b296fabb0 | ||
|
|
00c8f8acd0 | ||
|
|
1e1efa2c5e | ||
|
|
b0b0dd9f0b | ||
|
|
30bb1c52d0 | ||
|
|
7fc96a61ad | ||
|
|
4a164c39b4 | ||
|
|
b0e4069bb7 | ||
|
|
19cbb27b4c | ||
|
|
d44c864387 | ||
|
|
36e21e53e0 | ||
|
|
b7598cc354 | ||
|
|
0a4f322d49 | ||
|
|
bf013fcdae | ||
|
|
fd52fccc15 | ||
|
|
c493d3a4ce | ||
|
|
aeceb2b9e7 | ||
|
|
cb5f833dd2 | ||
|
|
0740ccd9f7 | ||
|
|
716c84c896 | ||
|
|
c5fda07d1e | ||
|
|
7fffe0abaa | ||
|
|
8a42325c23 | ||
|
|
78900304bf | ||
|
|
fb6dfbcd3c | ||
|
|
3dd4c7da2a | ||
|
|
03c955410c | ||
|
|
74f77c9ded | ||
|
|
3caca03e8a | ||
|
|
49469840ab | ||
|
|
85613ab02d | ||
|
|
6e4ce85c87 | ||
|
|
2a093dc183 | ||
|
|
01eeadbaf4 | ||
|
|
851b3a7cfb | ||
|
|
b6dc830bcb | ||
|
|
8ef02aae41 | ||
|
|
423dbd58a1 | ||
|
|
5582db615a | ||
|
|
1479ebfb5d | ||
|
|
4389ef1e77 | ||
|
|
5c305e7fa8 | ||
|
|
0427908eae | ||
|
|
2df53c3d27 | ||
|
|
53ec9adb1b | ||
|
|
8b95a22e75 | ||
|
|
665298a04b | ||
|
|
7e668df1fe | ||
|
|
85414cfec2 | ||
|
|
b973187960 | ||
|
|
991080e613 | ||
|
|
72bf199577 | ||
|
|
7bda43a6ec | ||
|
|
2b8b0ebe95 | ||
|
|
0aa61ce58f | ||
|
|
51a5dc78d7 | ||
|
|
232bd9a22b | ||
|
|
58327a1753 | ||
|
|
7844d84798 | ||
|
|
7a30a42797 | ||
|
|
094202ff16 | ||
|
|
9c4523f4fa | ||
|
|
69859c61e0 | ||
|
|
9878518e29 | ||
|
|
cde270728f | ||
|
|
5559d0fa68 | ||
|
|
8feff78526 | ||
|
|
226a3de55d | ||
|
|
67d0f5f4ae | ||
|
|
192f5e563c | ||
|
|
b6296e7a67 | ||
|
|
67e17d3bc3 | ||
|
|
64a6fef823 | ||
|
|
e0c64cc4ff | ||
|
|
3e55478b3b | ||
|
|
9aef821862 | ||
|
|
f394df840e | ||
|
|
7d33699173 | ||
|
|
d3ffe8c647 | ||
|
|
9b99f62311 | ||
|
|
3319ce78d3 | ||
|
|
8eabf43525 | ||
|
|
adb12bb7be | ||
|
|
3c10b36651 | ||
|
|
d37c300d87 | ||
|
|
9fc92e901e | ||
|
|
5b52529295 | ||
|
|
f77a7ad623 | ||
|
|
504ef9422e | ||
|
|
cbbcec0895 | ||
|
|
32d90c38db | ||
|
|
e1f7f3d7bb | ||
|
|
244536ea72 | ||
|
|
fa24a3e09e | ||
|
|
5ec26a5015 | ||
|
|
8a8ff2aef0 | ||
|
|
069254be6a | ||
|
|
f3cd74cb46 | ||
|
|
4be8aa0f91 | ||
|
|
93dd7a85f6 | ||
|
|
062596e3fb | ||
|
|
5af2de635e | ||
|
|
a16df91fbb | ||
|
|
44178b9103 | ||
|
|
b767f930ad | ||
|
|
ba61a6545a | ||
|
|
23ada5c7a5 | ||
|
|
97c37efffe | ||
|
|
5db95be4fc | ||
|
|
5897422c70 | ||
|
|
a7db0d3cc5 | ||
|
|
c49036a713 | ||
|
|
03246997fa | ||
|
|
f4eac6e4fc | ||
|
|
48f695f3e6 | ||
|
|
3525f044f5 | ||
|
|
b58f8b9d7c | ||
|
|
c00962e881 | ||
|
|
9bcf1d662b | ||
|
|
586e0721d8 | ||
|
|
882dd1f3a7 | ||
|
|
399291d783 | ||
|
|
46ac2e5252 | ||
|
|
a81818b2db | ||
|
|
9b0d112176 | ||
|
|
ac17df0c65 | ||
|
|
c4be4e7928 | ||
|
|
877cbbd11d | ||
|
|
b2bb03310e | ||
|
|
5c8885ee5f | ||
|
|
40ec6b263d | ||
|
|
3742da8770 | ||
|
|
19b06418c5 | ||
|
|
b7b8b9219d | ||
|
|
949966964f | ||
|
|
c0a0f9c1df | ||
|
|
7cff2fa8f1 | ||
|
|
c1b703a039 | ||
|
|
e0eff1d2bb | ||
|
|
037ef76ad8 | ||
|
|
ae8025cd5c | ||
|
|
1804cc3a09 | ||
|
|
2d8e6b45ec | ||
|
|
3fa52d0d7d | ||
|
|
6a7129d7af | ||
|
|
f0e113a532 | ||
|
|
8b3e415201 | ||
|
|
eb6a8afe8d | ||
|
|
a705a89e4a | ||
|
|
ea509c0a36 | ||
|
|
269600d875 | ||
|
|
95e3a8f3cc | ||
|
|
ffeff3ab69 | ||
|
|
bdc009eb65 | ||
|
|
683f65f8ac | ||
|
|
a737698372 | ||
|
|
eeecbbcff9 | ||
|
|
44b3d60692 | ||
|
|
641c7d1967 | ||
|
|
7923d1e930 | ||
|
|
42e072a868 | ||
|
|
97296934ab | ||
|
|
83dbe5fa3e | ||
|
|
b566b8b45a | ||
|
|
ecdfda56c2 | ||
|
|
166c4a244a | ||
|
|
be7bfbac39 | ||
|
|
3c8953672d | ||
|
|
045b196eeb | ||
|
|
d763fce8ed | ||
|
|
15c8ba5d3f | ||
|
|
1b75017c3c | ||
|
|
3ffe5e958f | ||
|
|
4f6a78cde8 | ||
|
|
3081d0766b | ||
|
|
c1e34cb9b5 | ||
|
|
dedf67fb52 | ||
|
|
a74fb940aa | ||
|
|
09275ae4ca | ||
|
|
657717d0fb | ||
|
|
4493d35d26 | ||
|
|
0d26ce9bcc | ||
|
|
fe77075996 | ||
|
|
4d6b126b9d | ||
|
|
7b1900d547 | ||
|
|
5a8c56e784 | ||
|
|
8c4cfc8101 | ||
|
|
5f1f5ffffd | ||
|
|
603c4b7672 | ||
|
|
4b49c63344 | ||
|
|
9bdc910327 | ||
|
|
730f50f770 | ||
|
|
91606a9e3f | ||
|
|
22b52f831b | ||
|
|
071b3f558f | ||
|
|
59cd4004ac | ||
|
|
7f7c1ff6c2 | ||
|
|
ad3acf355e | ||
|
|
4dcc4e3308 | ||
|
|
a9902b55d8 | ||
|
|
d46798c2a7 | ||
|
|
90623492b7 | ||
|
|
ddf3ba8a15 | ||
|
|
0c4d33d558 | ||
|
|
1c3b6ad59b | ||
|
|
473a12d700 | ||
|
|
774cfc4bdc | ||
|
|
509fbcc4f8 | ||
|
|
00862344f7 | ||
|
|
5ad2b0531a | ||
|
|
be8dbb0dc7 | ||
|
|
bdfa0b302b | ||
|
|
7541304a9a | ||
|
|
395a51eeca | ||
|
|
17e2d49c43 | ||
|
|
ac71c320cd | ||
|
|
0356bf6092 | ||
|
|
8bc1edd027 | ||
|
|
403f0dc8a5 | ||
|
|
dffa198ebd | ||
|
|
7028417d88 | ||
|
|
2d4ebba3ed | ||
|
|
aa3fda9c33 | ||
|
|
0f9f0b545e | ||
|
|
9fcc398540 | ||
|
|
61f4ab61cb | ||
|
|
1f481cbe54 | ||
|
|
f4ee10a96a | ||
|
|
9974be3fdc | ||
|
|
793171e9e0 | ||
|
|
cee7087d54 | ||
|
|
f9bcffcbd5 | ||
|
|
8fd7e87333 | ||
|
|
c436194d43 | ||
|
|
fcd160cc8c | ||
|
|
5adbadc901 | ||
|
|
5084279d81 | ||
|
|
bd21d0d0cf | ||
|
|
a3fd81540a | ||
|
|
ba3f6a5e76 | ||
|
|
25c56e86c9 | ||
|
|
0897b0969d | ||
|
|
6cb1c3c0e9 | ||
|
|
df257a8e8a | ||
|
|
71abdc1bda | ||
|
|
22de1dc0f2 | ||
|
|
6357b30712 | ||
|
|
b0e18d5e8a | ||
|
|
be58d73a0a | ||
|
|
c1f630f5ed | ||
|
|
ab75bfa6e7 | ||
|
|
a4e0225c69 | ||
|
|
6d3d6c3601 | ||
|
|
2872de75a0 | ||
|
|
70936e3738 | ||
|
|
c272883ec1 | ||
|
|
d9619a8fa4 | ||
|
|
9ec2022447 | ||
|
|
10f56c55e6 | ||
|
|
69682d6d97 | ||
|
|
b61575eb2b | ||
|
|
6942de4f57 | ||
|
|
8085e21a05 | ||
|
|
0061fe02e6 |
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
@@ -1,3 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: Issue template
|
||||||
|
about: Please fill this issue template for reporting Mongoose issues
|
||||||
|
#title:
|
||||||
|
#labels:
|
||||||
|
#assignees:
|
||||||
|
---
|
||||||
|
|
||||||
- My goal is: _describe_
|
- My goal is: _describe_
|
||||||
- My actions were: _describe_
|
- My actions were: _describe_
|
||||||
- My expectation was: _describe_
|
- My expectation was: _describe_
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
dry-run: false
|
dry-run: false
|
||||||
language: c++
|
language: c++
|
||||||
- name: Upload Crash
|
- name: Upload Crash
|
||||||
uses: actions/upload-artifact@v1
|
uses: actions/upload-artifact@v4
|
||||||
if: env.GO == 1 && failure() && steps.build.outcome == 'success'
|
if: env.GO == 1 && failure() && steps.build.outcome == 'success'
|
||||||
with:
|
with:
|
||||||
name: artifacts
|
name: artifacts
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ name: "CodeQL Scanning"
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '30 2 * * *' # run at 2:30 AM UTC
|
- cron: '30 23 * * *' # run at 11:30 PM UTC
|
||||||
# Allow manual runs
|
# Allow manual runs
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
@@ -17,11 +17,11 @@ jobs:
|
|||||||
permissions:
|
permissions:
|
||||||
security-events: write
|
security-events: write
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v2
|
uses: github/codeql-action/init@v3
|
||||||
with:
|
with:
|
||||||
languages: cpp
|
languages: cpp
|
||||||
- run: |
|
- run: |
|
||||||
@@ -29,4 +29,4 @@ jobs:
|
|||||||
./test/setup_ga_network.sh && make -C test mip_test CC=gcc ASAN= ASAN_OPTIONS=
|
./test/setup_ga_network.sh && make -C test mip_test CC=gcc ASAN= ASAN_OPTIONS=
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v2
|
uses: github/codeql-action/analyze@v3
|
||||||
+100
-56
@@ -1,7 +1,7 @@
|
|||||||
name: Full build and test
|
name: Full build and test
|
||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 1 * * *' # run at 1 AM UTC
|
- cron: '0 22 * * *' # run at 10 PM UTC
|
||||||
# Allow manual runs
|
# Allow manual runs
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
env:
|
env:
|
||||||
@@ -13,7 +13,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
cc: [gcc, clang, g++, clang++]
|
cc: [gcc, clang, g++, clang++]
|
||||||
target: [test, mip_test]
|
target: [test]
|
||||||
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
||||||
select: ["-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1"]
|
select: ["-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1"]
|
||||||
exclude:
|
exclude:
|
||||||
@@ -37,7 +37,23 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: ./test/setup_ga_network.sh && sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }}
|
- run: sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }}
|
||||||
|
mip:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
cc: [gcc, clang, g++, clang++]
|
||||||
|
target: [mip_test, mip_tap_test]
|
||||||
|
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
|
||||||
|
name: ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }}
|
||||||
|
env:
|
||||||
|
CC: ${{ matrix.cc }}
|
||||||
|
SSL: ${{ matrix.ssl }}
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: if [ "${{ matrix.target }}" == "mip_tap_test" ]; then ./test/setup_ga_network.sh ; fi && sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }} IPV6=0
|
||||||
s390:
|
s390:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@@ -48,7 +64,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390 SSL=${{ matrix.ssl }}
|
- run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390 SSL=${{ matrix.ssl }}
|
||||||
armhf:
|
armhf:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@@ -59,7 +75,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf SSL=${{ matrix.ssl }}
|
- run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf SSL=${{ matrix.ssl }}
|
||||||
unamalgamated-mg_prefix:
|
unamalgamated-mg_prefix:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@@ -101,7 +117,7 @@ jobs:
|
|||||||
name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
|
||||||
env:
|
env:
|
||||||
SSL: ${{ matrix.ssl }}
|
SSL: ${{ matrix.ssl }}
|
||||||
TFLAGS: ${{ matrix.select }} -DNO_SNTP_CHECK -Wno-sign-conversion # Workaround for MbedTLS 3.5.0
|
TFLAGS: ${{ matrix.select }} -Wno-sign-conversion # Workaround for MbedTLS 3.5.0
|
||||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -154,7 +170,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
name: examples ${{ matrix.ssl }}
|
name: examples ${{ matrix.ssl }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -285,10 +301,69 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: echo # nothing specific to install or do
|
- run: echo # nothing specific to install or do
|
||||||
- run: make -C examples/arduino arduino-xiao
|
- run: make -C examples/arduino arduino-xiao
|
||||||
|
# TODO(): - run: make -C examples/arduino arduino-esp32
|
||||||
|
# TODO(): - run: make -C examples/arduino arduino-teensy41
|
||||||
# - run: make -C examples/arduino arduino-nano
|
# - run: make -C examples/arduino arduino-nano
|
||||||
- run: make -C examples/arduino clean
|
- run: make -C examples/arduino clean
|
||||||
|
|
||||||
|
|
||||||
|
# wizard_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path: esp32/esp32-idf
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: echo # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
# - run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
wizard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: infineon/infineon-xmc7200
|
||||||
|
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
||||||
|
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
||||||
|
- path: nxp/rt1020-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1170-evk-make-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-2-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico2-picosdk-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-freertos-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-baremetal-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-freertos-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-freertos-builtin
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
- run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
generic_examples:
|
generic_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@@ -304,7 +379,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
|
|
||||||
- run: echo # nothing specific to install or do
|
- run: echo # nothing specific to install or do
|
||||||
- run: make -C examples/${{ matrix.example.path }} build
|
- run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
@@ -335,7 +409,7 @@ jobs:
|
|||||||
- path: nxp/nxp-lpcxpresso54628-lwip-freertos
|
- path: nxp/nxp-lpcxpresso54628-lwip-freertos
|
||||||
- path: nxp/nxp-twrk65f180m-lwip-freertos
|
- path: nxp/nxp-twrk65f180m-lwip-freertos
|
||||||
- path: nxp/nxp-twrkv58f220m-lwip-freertos
|
- path: nxp/nxp-twrkv58f220m-lwip-freertos
|
||||||
- path: rp2040/pico-rmii
|
- path: pico-sdk/pico-rmii
|
||||||
- path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis
|
||||||
- path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis
|
||||||
- path: stm32/nucleo-g031-make-baremetal-builtin
|
- path: stm32/nucleo-g031-make-baremetal-builtin
|
||||||
@@ -370,30 +444,15 @@ jobs:
|
|||||||
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
|
||||||
example:
|
example:
|
||||||
- path: microchip/same54-xpro/device-dashboard
|
- path: microchip/same54-xpro/device-dashboard
|
||||||
- path: nxp/rt1020-evk-make-baremetal-builtin
|
|
||||||
- path: nxp/rt1020-evk-make-freertos-builtin
|
- path: nxp/rt1020-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1060-evk-make-baremetal-builtin
|
|
||||||
- path: nxp/rt1060-evk-make-freertos-builtin
|
- path: nxp/rt1060-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1170-evk-make-baremetal-builtin
|
- path: nxp/rt1170-evk-make-freertos-builtin
|
||||||
- path: renesas/ek-ra6m4-make-baremetal-builtin
|
- path: renesas/ek-ra6m4-make-baremetal-builtin
|
||||||
- path: rp2040/pico-rndis-dashboard
|
- path: pico-sdk/pico-rndis-dashboard
|
||||||
- path: rp2040/pico-w
|
- path: pico-sdk/pico-w-picosdk-freertos-lwip
|
||||||
- path: rp2040/pico-w5500
|
- path: pico-sdk/pico-2-w-picosdk-freertos-lwip
|
||||||
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-f429zi-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-f746zg-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-f746zg-make-freertos-tcp
|
- path: stm32/nucleo-f746zg-make-freertos-tcp
|
||||||
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
|
||||||
- path: stm32/nucleo-h563zi-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-h563zi-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-h723zg-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-h743zi-make-freertos-builtin
|
|
||||||
- path: stm32/stm32h573i-dk-make-baremetal-builtin
|
|
||||||
- path: stm32/stm32h573i-dk-make-freertos-builtin
|
|
||||||
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
|
|
||||||
- path: ti/ek-tm4c1294xl-make-freertos-builtin
|
|
||||||
name: ${{ matrix.example.path }} ${{ matrix.ssl }}
|
name: ${{ matrix.example.path }} ${{ matrix.ssl }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -421,7 +480,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: rp2040/pico-rndis-device
|
- path: pico-sdk/pico-rndis-device
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -444,27 +503,12 @@ jobs:
|
|||||||
# - run: make -C examples/${{ matrix.example.path }} device_dashboard
|
# - run: make -C examples/${{ matrix.example.path }} device_dashboard
|
||||||
# - run: make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
# - run: make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
||||||
|
|
||||||
dual_examples_arm:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
example:
|
|
||||||
- path: stm32/nucleo-h723zg-make-baremetal-builtin
|
|
||||||
name: ${{ matrix.example.path }}
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with: { fetch-depth: 2 }
|
|
||||||
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
|
||||||
- run: make -C examples/${{ matrix.example.path }} device_dashboard
|
|
||||||
- run: make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
|
||||||
|
|
||||||
cube_examples:
|
cube_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: echo # nothing specific to install or do
|
- run: sudo pip install yq
|
||||||
- run: cd test/cube && make
|
- run: cd test/cube && make
|
||||||
|
|
||||||
zephyr_examples:
|
zephyr_examples:
|
||||||
@@ -473,7 +517,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/zephyr init
|
- run: make -C examples/zephyr init REPO=zephyrprojectrtos/ci:v0.26.14 # "no space left on device" with newers
|
||||||
- name: minify manifest
|
- name: minify manifest
|
||||||
uses: mikefarah/yq@master
|
uses: mikefarah/yq@master
|
||||||
with:
|
with:
|
||||||
@@ -497,8 +541,8 @@ jobs:
|
|||||||
- run: make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- name: Cube
|
- name: Cube
|
||||||
run: echo # nothing specific to install or do
|
run: echo # nothing specific to install or do
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
|
|
||||||
test_f4:
|
test_f4:
|
||||||
@@ -512,8 +556,8 @@ jobs:
|
|||||||
- run: make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- name: Cube
|
- name: Cube
|
||||||
run: echo # nothing specific to install or do
|
run: echo # nothing specific to install or do
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
|
|
||||||
test_h743:
|
test_h743:
|
||||||
@@ -525,10 +569,10 @@ jobs:
|
|||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- run: make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
- name: Cube
|
# - name: Cube
|
||||||
run: echo # nothing specific to install or do
|
# run: echo # nothing specific to install or do
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# - run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
|
|
||||||
test_h723:
|
test_h723:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -578,7 +622,7 @@ jobs:
|
|||||||
- name: baremetal
|
- name: baremetal
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
# - run: make -C examples/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C examples/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
test_ra6m4:
|
test_ra6m4:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -617,5 +661,5 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: SDK
|
- name: SDK
|
||||||
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
- run: make -C examples/rp2040/pico-w5500 test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
- run: make -C examples/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
+120
-127
@@ -25,7 +25,7 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: ./test/setup_ga_network.sh && make -C test ${{ matrix.target }}
|
run: make -C test ${{ matrix.target }}
|
||||||
s390:
|
s390:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -33,7 +33,7 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390
|
run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390
|
||||||
armhf:
|
armhf:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -41,7 +41,7 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf
|
run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf
|
||||||
unamalgamated-mg_prefix:
|
unamalgamated-mg_prefix:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
@@ -59,7 +59,7 @@ jobs:
|
|||||||
name: macos SSL=${{ matrix.ssl }}
|
name: macos SSL=${{ matrix.ssl }}
|
||||||
env:
|
env:
|
||||||
SSL: ${{ matrix.ssl }}
|
SSL: ${{ matrix.ssl }}
|
||||||
TFLAGS: -DNO_SNTP_CHECK
|
#TFLAGS: -DNO_SNTP_CHECK
|
||||||
HOMEBREW_NO_AUTO_UPDATE: 1
|
HOMEBREW_NO_AUTO_UPDATE: 1
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -173,6 +173,72 @@ jobs:
|
|||||||
- run: make -C test clean_tutorials_mac
|
- run: make -C test clean_tutorials_mac
|
||||||
|
|
||||||
|
|
||||||
|
# wizard_examples:
|
||||||
|
# runs-on: ubuntu-latest
|
||||||
|
# strategy:
|
||||||
|
# fail-fast: false
|
||||||
|
# matrix:
|
||||||
|
# example:
|
||||||
|
# - path: esp32/esp32-idf
|
||||||
|
# name: ${{ matrix.example.path }}
|
||||||
|
# env:
|
||||||
|
# GO: 0
|
||||||
|
# steps:
|
||||||
|
# - uses: actions/checkout@v4
|
||||||
|
# with: { fetch-depth: 2 }
|
||||||
|
# - run: |
|
||||||
|
# if ./test/match_changed_files.sh '^src'; then
|
||||||
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
|
# # nothing specific to install or do
|
||||||
|
# fi
|
||||||
|
# - if: ${{ env.GO == 1 }}
|
||||||
|
# run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
wizard_examples_arm:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example:
|
||||||
|
- path: infineon/infineon-xmc7200
|
||||||
|
- path: nxp/frdm-mcxn947-make-baremetal-builtin
|
||||||
|
- path: nxp/frdm-mcxn947-make-freertos-builtin
|
||||||
|
- path: nxp/rt1020-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1060-evk-make-baremetal-builtin
|
||||||
|
- path: nxp/rt1170-evk-make-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/pico-2-w-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin
|
||||||
|
- path: pico-sdk/w5500-evb-pico2-picosdk-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f429zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-f746zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h563zi-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h723zg-make-freertos-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
||||||
|
- path: stm32/nucleo-h743zi-make-freertos-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-baremetal-builtin
|
||||||
|
- path: stm32/stm32h573i-dk-make-freertos-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
|
||||||
|
- path: ti/ek-tm4c1294xl-make-freertos-builtin
|
||||||
|
name: ${{ matrix.example.path }}
|
||||||
|
env:
|
||||||
|
GO: 0
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with: { fetch-depth: 2 }
|
||||||
|
- run: |
|
||||||
|
if ./test/match_changed_files.sh '^src'; then
|
||||||
|
echo GO=1 >> $GITHUB_ENV
|
||||||
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
|
fi
|
||||||
|
- if: ${{ env.GO == 1 }}
|
||||||
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
|
|
||||||
generic_examples:
|
generic_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
@@ -242,30 +308,15 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: microchip/same54-xpro/device-dashboard
|
- path: microchip/same54-xpro/device-dashboard
|
||||||
- path: nxp/rt1020-evk-make-baremetal-builtin
|
|
||||||
- path: nxp/rt1020-evk-make-freertos-builtin
|
- path: nxp/rt1020-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1060-evk-make-baremetal-builtin
|
|
||||||
- path: nxp/rt1060-evk-make-freertos-builtin
|
- path: nxp/rt1060-evk-make-freertos-builtin
|
||||||
- path: nxp/rt1170-evk-make-baremetal-builtin
|
- path: nxp/rt1170-evk-make-freertos-builtin
|
||||||
- path: renesas/ek-ra6m4-make-baremetal-builtin
|
- path: renesas/ek-ra6m4-make-baremetal-builtin
|
||||||
- path: rp2040/pico-rndis-dashboard
|
- path: pico-sdk/pico-rndis-dashboard
|
||||||
- path: rp2040/pico-w
|
- path: pico-sdk/pico-w-picosdk-freertos-lwip
|
||||||
- path: rp2040/pico-w5500
|
- path: pico-sdk/pico-2-w-picosdk-freertos-lwip
|
||||||
- path: stm32/nucleo-f429zi-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-f429zi-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-f746zg-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-f746zg-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-f746zg-make-freertos-tcp
|
- path: stm32/nucleo-f746zg-make-freertos-tcp
|
||||||
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
|
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
|
||||||
- path: stm32/nucleo-h563zi-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-h563zi-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-h723zg-make-freertos-builtin
|
|
||||||
- path: stm32/nucleo-h743zi-make-baremetal-builtin
|
|
||||||
- path: stm32/nucleo-h743zi-make-freertos-builtin
|
|
||||||
- path: stm32/stm32h573i-dk-make-baremetal-builtin
|
|
||||||
- path: stm32/stm32h573i-dk-make-freertos-builtin
|
|
||||||
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
|
|
||||||
- path: ti/ek-tm4c1294xl-make-freertos-builtin
|
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
env:
|
env:
|
||||||
GO: 0
|
GO: 0
|
||||||
@@ -307,7 +358,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
example:
|
example:
|
||||||
- path: rp2040/pico-rndis-device
|
- path: pico-sdk/pico-rndis-device
|
||||||
name: ${{ matrix.example.path }}
|
name: ${{ matrix.example.path }}
|
||||||
env:
|
env:
|
||||||
GO: 0
|
GO: 0
|
||||||
@@ -322,64 +373,6 @@ jobs:
|
|||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/${{ matrix.example.path }} build
|
run: make -C examples/${{ matrix.example.path }} build
|
||||||
|
|
||||||
# dual_examples:
|
|
||||||
# runs-on: ubuntu-latest
|
|
||||||
# strategy:
|
|
||||||
# fail-fast: false
|
|
||||||
# matrix:
|
|
||||||
# example:
|
|
||||||
# - path:
|
|
||||||
# name: ${{ matrix.example.path }}
|
|
||||||
# env:
|
|
||||||
# GO: 0
|
|
||||||
# steps:
|
|
||||||
# - uses: actions/checkout@v4
|
|
||||||
# with: { fetch-depth: 2 }
|
|
||||||
# - run: |
|
|
||||||
# if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
|
||||||
# echo GO=1 >> $GITHUB_ENV
|
|
||||||
# # nothing specific to install or do
|
|
||||||
# fi
|
|
||||||
# - if: ${{ env.GO == 1 }}
|
|
||||||
# run: |
|
|
||||||
# if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
|
||||||
# make -C examples/${{ matrix.example.path }} device_dashboard
|
|
||||||
# fi
|
|
||||||
# - if: ${{ env.GO == 1 }}
|
|
||||||
# run: |
|
|
||||||
# if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
|
||||||
# make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
|
||||||
# fi
|
|
||||||
|
|
||||||
dual_examples_arm:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
example:
|
|
||||||
- path: stm32/nucleo-h723zg-make-baremetal-builtin
|
|
||||||
name: ${{ matrix.example.path }}
|
|
||||||
env:
|
|
||||||
GO: 0
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
with: { fetch-depth: 2 }
|
|
||||||
- run: |
|
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
|
||||||
echo GO=1 >> $GITHUB_ENV
|
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
|
||||||
fi
|
|
||||||
- if: ${{ env.GO == 1 }}
|
|
||||||
run: |
|
|
||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
|
|
||||||
make -C examples/${{ matrix.example.path }} device_dashboard
|
|
||||||
fi
|
|
||||||
- if: ${{ env.GO == 1 }}
|
|
||||||
run: |
|
|
||||||
if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
|
|
||||||
make -C examples/${{ matrix.example.path }} mqtt_dashboard
|
|
||||||
fi
|
|
||||||
|
|
||||||
cube_examples:
|
cube_examples:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
env:
|
env:
|
||||||
@@ -390,7 +383,7 @@ jobs:
|
|||||||
- run: |
|
- run: |
|
||||||
if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-*-cube-*'; then
|
if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-*-cube-*'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
# nothing specific to install or do
|
sudo pip install yq
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: cd test/cube && make
|
run: cd test/cube && make
|
||||||
@@ -432,16 +425,16 @@ jobs:
|
|||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
# nothing specific to install or do
|
# nothing specific to install or do
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
run: |
|
# run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-baremetal-builtin'; then
|
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-baremetal-builtin'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
run: |
|
# run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-freertos-builtin'; then
|
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-freertos-builtin'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
|
||||||
fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-freertos-lwip'; then
|
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-freertos-lwip'; then
|
||||||
@@ -480,16 +473,16 @@ jobs:
|
|||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
# nothing specific to install or do
|
# nothing specific to install or do
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
run: |
|
# run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-baremetal-builtin'; then
|
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-baremetal-builtin'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
run: |
|
# run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-freertos-builtin'; then
|
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-freertos-builtin'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
|
||||||
fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-freertos-lwip'; then
|
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-freertos-lwip'; then
|
||||||
@@ -520,23 +513,23 @@ jobs:
|
|||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-make-freertos-builtin'; then
|
||||||
make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
- name: Cube
|
# - name: Cube
|
||||||
run: |
|
# run: |
|
||||||
echo GO=0 >> $GITHUB_ENV
|
# echo GO=0 >> $GITHUB_ENV
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h74.*-cube-'; then
|
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-h74.*-cube-'; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
# echo GO=1 >> $GITHUB_ENV
|
||||||
# nothing specific to install or do
|
# # nothing specific to install or do
|
||||||
fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
run: |
|
# run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-cube-baremetal-builtin'; then
|
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-cube-baremetal-builtin'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
fi
|
# fi
|
||||||
- if: ${{ env.GO == 1 }}
|
# - if: ${{ env.GO == 1 }}
|
||||||
run: |
|
# run: |
|
||||||
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-cube-freertos-builtin'; then
|
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-cube-freertos-builtin'; then
|
||||||
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
# make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
|
||||||
fi
|
# fi
|
||||||
|
|
||||||
test_h723:
|
test_h723:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -657,11 +650,11 @@ jobs:
|
|||||||
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1170-evk-make-baremetal-builtin'; then
|
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1170-evk-make-baremetal-builtin'; then
|
||||||
make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
fi
|
fi
|
||||||
# - if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
# run: |
|
run: |
|
||||||
# if ./test/match_changed_files.sh 'examples/nxp/rt1170-evk-make-freertos-builtin'; then
|
if ./test/match_changed_files.sh 'examples/nxp/rt1170-evk-make-freertos-builtin'; then
|
||||||
# make -C examples/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
make -C examples/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
# fi
|
fi
|
||||||
|
|
||||||
test_ra6m4:
|
test_ra6m4:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -745,10 +738,10 @@ jobs:
|
|||||||
with: { fetch-depth: 2 }
|
with: { fetch-depth: 2 }
|
||||||
- name: SDK
|
- name: SDK
|
||||||
run: |
|
run: |
|
||||||
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/rp2040/pico-w5500" ; then
|
if ./test/match_changed_files.sh "^src" ; then
|
||||||
echo GO=1 >> $GITHUB_ENV
|
echo GO=1 >> $GITHUB_ENV
|
||||||
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
|
||||||
fi
|
fi
|
||||||
- if: ${{ env.GO == 1 }}
|
- if: ${{ env.GO == 1 }}
|
||||||
run: make -C examples/rp2040/pico-w5500 test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
run: make -C examples/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
Copyright (c) 2004-2013 Sergey Lyubka
|
Copyright (c) 2004-2013 Sergey Lyubka
|
||||||
Copyright (c) 2013-2024 Cesanta Software Limited
|
Copyright (c) 2013-2025 Cesanta Software Limited
|
||||||
All rights reserved
|
All rights reserved
|
||||||
|
|
||||||
This software is dual-licensed: you can redistribute it and/or modify
|
This software is dual-licensed: you can redistribute it and/or modify
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
[](https://github.com/cesanta/mongoose/actions)
|
[](https://github.com/cesanta/mongoose/actions)
|
||||||
[](https://codecov.io/gh/cesanta/mongoose)
|
[](https://codecov.io/gh/cesanta/mongoose)
|
||||||
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
[](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
||||||
|
[](https://gurubase.io/g/mongoose)
|
||||||
|
|
||||||
Mongoose is a network library for C/C++. It provides event-driven non-blocking
|
Mongoose is a network library for C/C++. It provides event-driven non-blocking
|
||||||
APIs for TCP, UDP, HTTP, WebSocket, MQTT, and other protocols. It is designed
|
APIs for TCP, UDP, HTTP, WebSocket, MQTT, and other protocols. It is designed
|
||||||
@@ -14,7 +15,7 @@ robust, and easy. Features include:
|
|||||||
|
|
||||||
- Cross-platform:
|
- Cross-platform:
|
||||||
- works on Linux/UNIX, MacOS, Windows, Android
|
- works on Linux/UNIX, MacOS, Windows, Android
|
||||||
- works on STM32, NXP, ESP32, NRF52, TI, Microchip, and other
|
- works on ST, NXP, ESP32, Nordic, TI, Microchip, Infineon, Renesas and other chips
|
||||||
- write code once - and it'll work everywhere
|
- write code once - and it'll work everywhere
|
||||||
- ideal for the unification of the network infrastructure code across company
|
- ideal for the unification of the network infrastructure code across company
|
||||||
- Built-in protocols: plain TCP/UDP, SNTP, HTTP, MQTT, Websocket, and other
|
- Built-in protocols: plain TCP/UDP, SNTP, HTTP, MQTT, Websocket, and other
|
||||||
@@ -70,7 +71,7 @@ HTTP server implements a REST API that returns current time. JSON formatting:
|
|||||||
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
if (ev == MG_EV_HTTP_MSG) {
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
if (mg_http_match_uri(hm, "/api/time/get")) {
|
if (mg_match(hm->uri, mg_str("/api/time/get"), NULL)) {
|
||||||
mg_http_reply(c, 200, "", "{%m:%lu}\n", MG_ESC("time"), time(NULL));
|
mg_http_reply(c, 200, "", "{%m:%lu}\n", MG_ESC("time"), time(NULL));
|
||||||
} else {
|
} else {
|
||||||
mg_http_reply(c, 500, "", "{%m:%m}\n", MG_ESC("error"), MG_ESC("Unsupported URI"));
|
mg_http_reply(c, 500, "", "{%m:%m}\n", MG_ESC("error"), MG_ESC("Unsupported URI"));
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ arduino-xiao-board:
|
|||||||
./arduino/arduino --install-boards Seeeduino:samd
|
./arduino/arduino --install-boards Seeeduino:samd
|
||||||
|
|
||||||
arduino-xiao: arduino arduino-xiao-board
|
arduino-xiao: arduino arduino-xiao-board
|
||||||
|
cd sim800-mqtt && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 sim800-mqtt.ino
|
||||||
cd w5500-http && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-http.ino
|
cd w5500-http && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-http.ino
|
||||||
cd w5500-mqtt && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-mqtt.ino
|
cd w5500-mqtt && ../arduino/arduino --verbose --verify --board Seeeduino:samd:seeed_XIAO_m0 w5500-mqtt.ino
|
||||||
|
|
||||||
@@ -21,6 +22,18 @@ arduino-nano: arduino
|
|||||||
cd w5500-http && ../arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-http.ino
|
cd w5500-http && ../arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-http.ino
|
||||||
cd w5500-mqtt && ../arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-mqtt.ino
|
cd w5500-mqtt && ../arduino/arduino --pref compiler.cpp.extra_flags=-DMG_ENABLE_LOG=0 --verbose --verify --board arduino:avr:nano w5500-mqtt.ino
|
||||||
|
|
||||||
|
arduino-esp32: arduino
|
||||||
|
# cd esp32-http && ../arduino/arduino --verbose --verify --board esp32-http.ino
|
||||||
|
# esp32-mqtt
|
||||||
|
|
||||||
|
arduino-teensy41: arduino
|
||||||
|
# cd teensy41-http && ../arduino/arduino --verbose --verify --board teensy41-http.ino
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf arduino
|
rm -rf arduino
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
#include "mongoose.h"
|
||||||
|
#include "WiFi.h"
|
||||||
|
|
||||||
|
#define LED_PIN LED_BUILTIN
|
||||||
|
#define WIFI_SSID "wifi_network_name" // Change this
|
||||||
|
#define WIFI_PASS "wifi_password" // And this
|
||||||
|
|
||||||
|
struct mg_mgr mgr;
|
||||||
|
|
||||||
|
// Crude function to get available RAM, for quick profiling
|
||||||
|
size_t getFreeRAM(void) {
|
||||||
|
size_t size = 0, increment = 1024;
|
||||||
|
void *p;
|
||||||
|
while ((p = malloc(size)) != NULL) free(p), size += increment;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
|
||||||
|
if (mg_match(hm->uri, mg_str("/api/led/on"), NULL)) {
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
|
mg_http_reply(c, 200, "", "{%m: %d}\n", MG_ESC("led"), digitalRead(LED_PIN));
|
||||||
|
} else if (mg_match(hm->uri, mg_str("/api/led/off"), NULL)) {
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
|
mg_http_reply(c, 200, "", "{%m: %d}\n", MG_ESC("led"), digitalRead(LED_PIN));
|
||||||
|
} else {
|
||||||
|
mg_http_reply(c, 200, "", "ok, free RAM: %u\n", xPortGetFreeHeapSize());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(LED_PIN, OUTPUT);
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(50);
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||||
|
while(WiFi.status() != WL_CONNECTED) Serial.print("."), delay(100);
|
||||||
|
|
||||||
|
Serial.println("\nConnected to the WiFi network");
|
||||||
|
Serial.print("IP Address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr);
|
||||||
|
mg_log_set(MG_LL_DEBUG);
|
||||||
|
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
|
||||||
|
mg_http_listen(&mgr, "http://0.0.0.0", http_ev_handler, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
mg_mgr_poll(&mgr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp) __attribute__((weak));
|
||||||
|
extern "C" int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp) {
|
||||||
|
if (ip6_addr_isany_val(inp->ip6_addr[0].u_addr.ip6)) {
|
||||||
|
pbuf_free(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MG_ARCH MG_ARCH_ESP32
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
#include "WiFi.h"
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
#define WIFI_SSID "wifi_network_name" // Change this
|
||||||
|
#define WIFI_PASS "wifi_password" // And this
|
||||||
|
|
||||||
|
#define MQTT_SERVER "mqtt://broker.hivemq.com:1883"
|
||||||
|
#define MQTT_SUB_TOPIC "mg/rx" // Subscribe to this topic
|
||||||
|
#define MQTT_PUB_TOPIC "mg/tx" // Publish to this topic
|
||||||
|
|
||||||
|
#define LED_PIN 0
|
||||||
|
|
||||||
|
struct mg_mgr mgr;
|
||||||
|
struct mg_connection *mqtt_connection;
|
||||||
|
|
||||||
|
void mqtt_publish(const char *message) {
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.topic = mg_str(MQTT_PUB_TOPIC);
|
||||||
|
opts.message = mg_str(message);
|
||||||
|
if (mqtt_connection) mg_mqtt_pub(mqtt_connection, &opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crude function to get available RAM, for quick profiling
|
||||||
|
size_t getFreeRAM(void) {
|
||||||
|
size_t size = 0, increment = 100;
|
||||||
|
void *p;
|
||||||
|
while ((p = malloc(size)) != NULL) free(p), size += increment;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement LED control over MQTT: "on" and "off" commands
|
||||||
|
void handle_command(struct mg_str msg) {
|
||||||
|
if (msg.len == 3 && memcmp(msg.buf, "off", 3) == 0) {
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
|
mqtt_publish("done - off");
|
||||||
|
} else if (msg.len == 2 && memcmp(msg.buf, "on", 2) == 0) {
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
|
mqtt_publish("done - on");
|
||||||
|
}
|
||||||
|
MG_INFO(("Free RAM: %u bytes", getFreeRAM()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mqtt_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_MQTT_OPEN) {
|
||||||
|
MG_INFO(("%lu CONNECTED to %s", c->id, MQTT_SERVER));
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.topic = mg_str(MQTT_SUB_TOPIC);
|
||||||
|
mg_mqtt_sub(c, &opts);
|
||||||
|
MG_INFO(("%lu SUBSCRIBED to %s", c->id, MQTT_SUB_TOPIC));
|
||||||
|
} else if (ev == MG_EV_MQTT_MSG) {
|
||||||
|
// Received MQTT message
|
||||||
|
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
||||||
|
MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, (int) mm->data.len,
|
||||||
|
mm->data.buf, (int) mm->topic.len, mm->topic.buf));
|
||||||
|
handle_command(mm->data);
|
||||||
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
|
MG_INFO(("%lu CLOSED", c->id));
|
||||||
|
mqtt_connection = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reconnect_if_not_connected(void) {
|
||||||
|
if (mqtt_connection == NULL) {
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.clean = true;
|
||||||
|
mqtt_connection =
|
||||||
|
mg_mqtt_connect(&mgr, MQTT_SERVER, &opts, mqtt_ev_handler, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
pinMode(LED_PIN, OUTPUT);
|
||||||
|
Serial.begin(115200);
|
||||||
|
while (!Serial) delay(50);
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
|
WiFi.begin(WIFI_SSID, WIFI_PASS);
|
||||||
|
while (WiFi.status() != WL_CONNECTED) Serial.print("."), delay(100);
|
||||||
|
|
||||||
|
Serial.println("\nConnected to the WiFi network");
|
||||||
|
Serial.print("IP Address: ");
|
||||||
|
Serial.println(WiFi.localIP());
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr);
|
||||||
|
mg_log_set(MG_LL_DEBUG);
|
||||||
|
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
mg_mgr_poll(&mgr, 1); // Process network events
|
||||||
|
reconnect_if_not_connected(); // Reconnect to MQTT server if needed
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp)
|
||||||
|
__attribute__((weak));
|
||||||
|
extern "C" int lwip_hook_ip6_input(struct pbuf *p, struct netif *inp) {
|
||||||
|
if (ip6_addr_isany_val(inp->ip6_addr[0].u_addr.ip6)) {
|
||||||
|
pbuf_free(p);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define MG_ARCH MG_ARCH_ESP32
|
||||||
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Arduino.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#define MG_ARCH MG_ARCH_CUSTOM
|
||||||
|
#define MG_ENABLE_SOCKET 0
|
||||||
|
#define MG_ENABLE_TCPIP 1
|
||||||
|
#define MG_ENABLE_DRIVER_PPP 1
|
||||||
|
#define MG_ENABLE_TCPIP_DRIVER_INIT 0
|
||||||
|
#define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0
|
||||||
|
#define MG_ENABLE_CUSTOM_MILLIS 1
|
||||||
|
#define MG_ENABLE_CUSTOM_RANDOM 1
|
||||||
|
#define MG_TLS MG_TLS_BUILTIN
|
||||||
|
#define MG_IO_SIZE 128
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
#include <SoftwareSerial.h>
|
||||||
|
#include "mongoose.h"
|
||||||
|
|
||||||
|
#define MQTT_SERVER "mqtt://broker.hivemq.com:8883"
|
||||||
|
#define MQTT_SUB_TOPIC "mg/rx" // Subscribe to this topic
|
||||||
|
#define MQTT_PUB_TOPIC "mg/tx" // Publish to this topic
|
||||||
|
|
||||||
|
static const char *script[] = {
|
||||||
|
"AT\r\n", "*OK\r\n",
|
||||||
|
"ATZ\r\n", "*OK\r\n",
|
||||||
|
"AT+CPIN?\r\n", "*OK\r\n",
|
||||||
|
"AT+CNMI=0,0,0,0,0\r\n", "*OK\r\n",
|
||||||
|
"AT+CGDCONT=1,\"IP\",\"iot.1nce.net\"\r\n", "*OK\r\n",
|
||||||
|
"AT+CGDATA=\"PPP\",1\r\n", "*CONNECT\r\n",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Visit https://mongoose.ws/tls/ and copy-paste CA certificate for your server
|
||||||
|
#define TLS_CA \
|
||||||
|
""
|
||||||
|
|
||||||
|
// We use Serial1 or software serial to communicate with the modem
|
||||||
|
#define LED_PIN LED_BUILTIN
|
||||||
|
#define RST_PIN 10
|
||||||
|
#define ModemSerial Serial1
|
||||||
|
//#define RX_PIN 9
|
||||||
|
//#define TX_PIN 8
|
||||||
|
//SoftwareSerial ModemSerial(RX_PIN, TX_PIN);
|
||||||
|
|
||||||
|
struct mg_connection *mqtt_connection;
|
||||||
|
struct mg_tcpip_driver_ppp_data driver_data;
|
||||||
|
struct mg_mgr mgr; // Mongoose event manager
|
||||||
|
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // Network interface
|
||||||
|
|
||||||
|
uint64_t mg_millis(void) {
|
||||||
|
return millis();
|
||||||
|
}
|
||||||
|
bool mg_random(void *buf, size_t len) { // For TLS
|
||||||
|
uint8_t *p = (uint8_t *) buf;
|
||||||
|
while (len--) *p++ = (unsigned char) (rand() & 255);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mqtt_publish(const char *message) {
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.topic = mg_str(MQTT_PUB_TOPIC);
|
||||||
|
opts.message = mg_str(message);
|
||||||
|
if (mqtt_connection) mg_mqtt_pub(mqtt_connection, &opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_command(struct mg_str msg) {
|
||||||
|
if (msg.len == 3 && memcmp(msg.buf, "off", 3) == 0) {
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
|
mqtt_publish("done - off");
|
||||||
|
} else if (msg.len == 2 && memcmp(msg.buf, "on", 2) == 0) {
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
|
mqtt_publish("done - on");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mqtt_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_CONNECT && mg_url_is_ssl(MQTT_SERVER)) {
|
||||||
|
struct mg_tls_opts opts = {};
|
||||||
|
opts.ca = mg_str(TLS_CA);
|
||||||
|
mg_tls_init(c, &opts);
|
||||||
|
}
|
||||||
|
if (ev == MG_EV_MQTT_OPEN) {
|
||||||
|
MG_INFO(("%lu CONNECTED to %s", c->id, MQTT_SERVER));
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.topic = mg_str(MQTT_SUB_TOPIC);
|
||||||
|
mg_mqtt_sub(c, &opts);
|
||||||
|
MG_INFO(("%lu SUBSCRIBED to %s", c->id, MQTT_SUB_TOPIC));
|
||||||
|
} else if (ev == MG_EV_MQTT_MSG) {
|
||||||
|
// Received MQTT message
|
||||||
|
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
||||||
|
MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, (int) mm->data.len,
|
||||||
|
mm->data.buf, (int) mm->topic.len, mm->topic.buf));
|
||||||
|
handle_command(mm->data);
|
||||||
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
|
MG_INFO(("%lu CLOSED", c->id));
|
||||||
|
mqtt_connection = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reconnect_if_not_connected(void) {
|
||||||
|
if (mif.state == MG_TCPIP_STATE_READY && mqtt_connection == NULL) {
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.clean = true;
|
||||||
|
mqtt_connection =
|
||||||
|
mg_mqtt_connect(&mgr, MQTT_SERVER, &opts, mqtt_ev_handler, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial.begin(115200); // Initialise serial for logs
|
||||||
|
while (!Serial) delay(50); // for debug output
|
||||||
|
|
||||||
|
pinMode(LED_PIN, OUTPUT); // Initialise pins
|
||||||
|
pinMode(RST_PIN, OUTPUT);
|
||||||
|
digitalWrite(RST_PIN, HIGH);
|
||||||
|
//pinMode(RX_PIN, INPUT); // Only required for
|
||||||
|
//pinMode(TX_PIN, OUTPUT); // software serial
|
||||||
|
ModemSerial.begin(115200); // Serial for modem communication
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr); // Initialise Mongoose event manager
|
||||||
|
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
||||||
|
mg_log_set_fn([](char c, void *) { Serial.print(c); }, NULL); // Log serial
|
||||||
|
|
||||||
|
mif.driver = &mg_tcpip_driver_ppp; // Initialise built-in TCP/IP stack
|
||||||
|
mif.driver_data = &driver_data; // with the cellular driver
|
||||||
|
driver_data.script = script;
|
||||||
|
driver_data.reset = [](void *) { digitalWrite(RST_PIN, LOW); delay(1); digitalWrite(RST_PIN, HIGH); },
|
||||||
|
driver_data.tx = [](void *, uint8_t c) { ModemSerial.write(c); },
|
||||||
|
driver_data.rx = [](void *) { return ModemSerial.available() ? ModemSerial.read() : -1; },
|
||||||
|
mg_tcpip_init(&mgr, &mif);
|
||||||
|
mif.enable_dhcp_client = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
mg_mgr_poll(&mgr, 1); // Process network events
|
||||||
|
reconnect_if_not_connected(); // Reconnect to MQTT server if needed
|
||||||
|
}
|
||||||
@@ -8,9 +8,11 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
#define MG_ARCH MG_ARCH_CUSTOM
|
#define MG_ARCH MG_ARCH_CUSTOM
|
||||||
#define MG_ENABLE_SOCKET 0
|
|
||||||
#define MG_ENABLE_TCPIP 1
|
#define MG_ENABLE_TCPIP 1
|
||||||
#define MG_ENABLE_DRIVER_W5500 1
|
#define MG_ENABLE_DRIVER_W5500 1
|
||||||
#define mkdir(a, b) (-1)
|
#define MG_ENABLE_TCPIP_DRIVER_INIT 0
|
||||||
#define MG_IO_SIZE 128
|
#define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0
|
||||||
//#define MG_ENABLE_LOG 0
|
#define MG_ENABLE_CUSTOM_MILLIS 1
|
||||||
|
#define MG_ENABLE_CUSTOM_RANDOM 1
|
||||||
|
#define MG_TLS MG_TLS_BUILTIN
|
||||||
|
#define MG_IO_SIZE 256
|
||||||
@@ -1,47 +1,108 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include "mongoose.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
#define SS_PIN 3 // Slave select pin
|
#define LED_PIN LED_BUILTIN // LED pin
|
||||||
struct mg_mgr mgr; // Mongoose event manager
|
#define SS_PIN 17 // Slave select pin for the W5500 module
|
||||||
|
|
||||||
struct mg_tcpip_spi spi = {
|
struct mg_tcpip_spi spi = {
|
||||||
NULL, // SPI data
|
NULL, // SPI metadata
|
||||||
[](void *) { digitalWrite(SS_PIN, LOW); }, // begin transation
|
[](void *) { digitalWrite(SS_PIN, LOW); SPI.beginTransaction(SPISettings()); },
|
||||||
[](void *) { digitalWrite(SS_PIN, HIGH); }, // end transaction
|
[](void *) { digitalWrite(SS_PIN, HIGH); SPI.endTransaction(); },
|
||||||
[](void *, uint8_t c) { return SPI.transfer(c); }, // execute transaction
|
[](void *, uint8_t c) { return SPI.transfer(c); }, // Execute transaction
|
||||||
};
|
};
|
||||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // network interface
|
struct mg_mgr mgr; // Mongoose event manager
|
||||||
|
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // Network interface
|
||||||
|
|
||||||
|
// Used by Mongoose for time tracking
|
||||||
|
uint64_t mg_millis(void) {
|
||||||
|
return millis();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by Mongoose to generate random data
|
||||||
|
bool mg_random(void *buf, size_t len) { // For TLS
|
||||||
|
uint8_t *p = (uint8_t *) buf;
|
||||||
|
while (len--) *p++ = (unsigned char) (rand() & 255);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crude function to get available RAM, for quick profiling
|
||||||
|
extern "C" char *sbrk(int);
|
||||||
|
extern char *__brkval;
|
||||||
|
int getFreeRAM() {
|
||||||
|
char top;
|
||||||
|
#ifdef __arm__
|
||||||
|
return &top - (char *) sbrk(0);
|
||||||
|
#elif defined(CORE_TEENSY) || (ARDUINO > 103 && ARDUINO != 151)
|
||||||
|
return &top - __brkval;
|
||||||
|
#else
|
||||||
|
return __brkval ? &top - __brkval : &top - __malloc_heap_start;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void http_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_HTTP_MSG) {
|
||||||
|
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
|
||||||
|
if (mg_match(hm->uri, mg_str("/api/led/on"), NULL)) {
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
|
mg_http_reply(c, 200, "", "{%m: %d}\n", MG_ESC("led"), digitalRead(LED_PIN));
|
||||||
|
} else if (mg_match(hm->uri, mg_str("/api/led/off"), NULL)) {
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
|
mg_http_reply(c, 200, "", "{%m: %d}\n", MG_ESC("led"), digitalRead(LED_PIN));
|
||||||
|
} else {
|
||||||
|
mg_http_reply(c, 200, "", "ok, free RAM: %u\n", getFreeRAM());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Initialise TLS if we're a TLS listener
|
||||||
|
if (ev == MG_EV_ACCEPT && c->fn_data != NULL) {
|
||||||
|
struct mg_tls_opts opts;
|
||||||
|
memset(&opts, 0, sizeof(opts));
|
||||||
|
|
||||||
|
// Generated by https://mongoose.ws/tls/
|
||||||
|
#define TLS_CERT \
|
||||||
|
"-----BEGIN CERTIFICATE-----\n" \
|
||||||
|
"MIIBkzCCATqgAwIBAgIEZ3E9lzAKBggqhkjOPQQDAjATMREwDwYDVQQDEwhNb25n\n" \
|
||||||
|
"b29zZTAeFw0yNDEyMjkxMjE2MjNaFw0zNDEyMjcxMjE2MjNaMBQxEjAQBgNVBAMT\n" \
|
||||||
|
"CWxvY2FsaG9zdDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHxxuByu5K2k7DYq\n" \
|
||||||
|
"b3eQsHb3VY5NWglWun7axh69OWF7V9OUUyON1y8ISirL0Gj5ZPOogIgrB9iOcz6K\n" \
|
||||||
|
"q9n8NQOjezB5MA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggrBgEFBQcDATAM\n" \
|
||||||
|
"BgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFGn8GpPWaM0JC7U4zlg+bCljSjLoMCMG\n" \
|
||||||
|
"A1UdEQQcMBqCCWxvY2FsaG9zdIINMTkyLjE2OC4wLjEwMDAKBggqhkjOPQQDAgNH\n" \
|
||||||
|
"ADBEAiAr1fO3QLLm+vjYarctNI+gfnxxB4edRTRmcFWHmBS8oQIgY5lkq2JCwATG\n" \
|
||||||
|
"YsVQUmS+2Tbc7ij7lkduXO42pvr/0fw=\n" \
|
||||||
|
"-----END CERTIFICATE-----"
|
||||||
|
|
||||||
|
#define TLS_KEY \
|
||||||
|
"-----BEGIN EC PRIVATE KEY-----\n" \
|
||||||
|
"MHcCAQEEIHKu84eEw9dX8nez82g3F94OsZJ14LVbAN+OBW+++V2poAoGCCqGSM49\n" \
|
||||||
|
"AwEHoUQDQgAEfHG4HK7kraTsNipvd5CwdvdVjk1aCVa6ftrGHr05YXtX05RTI43X\n" \
|
||||||
|
"LwhKKsvQaPlk86iAiCsH2I5zPoqr2fw1Aw==\n" \
|
||||||
|
"-----END EC PRIVATE KEY-----"
|
||||||
|
|
||||||
|
opts.cert = mg_str(TLS_CERT);
|
||||||
|
opts.key = mg_str(TLS_KEY);
|
||||||
|
|
||||||
|
mg_tls_init(c, &opts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200); // Initialise serial
|
||||||
pinMode(SS_PIN, OUTPUT);
|
while (!Serial) delay(50); // for debug output
|
||||||
SPI.begin();
|
|
||||||
|
|
||||||
// Set logging function to a serial print
|
SPI.begin(); // Iniitialise SPI
|
||||||
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
|
pinMode(SS_PIN, OUTPUT); // to communicate with W5500 Ethernet module
|
||||||
mg_mgr_init(&mgr);
|
pinMode(LED_PIN, OUTPUT); // Initialise LED
|
||||||
|
|
||||||
delay(3000);
|
mg_mgr_init(&mgr); // Initialise Mongoose event manager
|
||||||
MG_INFO(("Starting TCP/IP stack..."));
|
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
||||||
|
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL); // Log serial
|
||||||
|
mif.driver = &mg_tcpip_driver_w5500; // Use W5500 built-in driver
|
||||||
|
mif.driver_data = &spi; // Pass SPI interface to W5500 driver
|
||||||
|
mg_tcpip_init(&mgr, &mif); // Initialise built-in TCP/IP stack
|
||||||
|
|
||||||
mif.driver = &mg_tcpip_driver_w5500;
|
// Setup HTTP & HTTPS listeners. Respond "ok" on any HTTP request
|
||||||
mif.driver_data = &spi;
|
mg_http_listen(&mgr, "http://0.0.0.0:80", http_ev_handler, NULL);
|
||||||
mg_tcpip_init(&mgr, &mif);
|
mg_http_listen(&mgr, "https://0.0.0.0:443", http_ev_handler, (void *) 1);
|
||||||
|
|
||||||
// Start a 5 sec timer, print status message periodically
|
|
||||||
mg_timer_add(
|
|
||||||
&mgr, 5000, MG_TIMER_REPEAT,
|
|
||||||
[](void *) {
|
|
||||||
MG_INFO(("ethernet: %s", mg_tcpip_driver_w5500.up(&mif) ? "up" : "down"));
|
|
||||||
},
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
// Setup HTTP listener. Respond "ok" on any HTTP request
|
|
||||||
mg_http_listen(
|
|
||||||
&mgr, "http://0.0.0.0",
|
|
||||||
[](struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
if (ev == MG_EV_HTTP_MSG) mg_http_reply(c, 200, "", "ok\n");
|
|
||||||
},
|
|
||||||
&mgr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|||||||
@@ -11,6 +11,10 @@
|
|||||||
#define MG_ENABLE_SOCKET 0
|
#define MG_ENABLE_SOCKET 0
|
||||||
#define MG_ENABLE_TCPIP 1
|
#define MG_ENABLE_TCPIP 1
|
||||||
#define MG_ENABLE_DRIVER_W5500 1
|
#define MG_ENABLE_DRIVER_W5500 1
|
||||||
#define mkdir(a, b) (-1)
|
#define MG_ENABLE_TCPIP_DRIVER_INIT 0
|
||||||
#define MG_IO_SIZE 512
|
#define MG_ENABLE_TCPIP_PRINT_DEBUG_STATS 0
|
||||||
//#define MG_ENABLE_LOG 0
|
#define MG_ENABLE_CUSTOM_MILLIS 1
|
||||||
|
#define MG_ENABLE_CUSTOM_RANDOM 1
|
||||||
|
// #define MG_TLS MG_TLS_BUILTIN
|
||||||
|
#define MG_IO_SIZE 128
|
||||||
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#include "net.h"
|
|
||||||
|
|
||||||
#define MQTT_SERVER "mqtt://broker.hivemq.com:1883"
|
|
||||||
struct mg_connection *mqtt_connection;
|
|
||||||
const char *mqtt_subscribe_topic = "mg/rx";
|
|
||||||
const char *mqtt_publish_topic = "mg/tx";
|
|
||||||
|
|
||||||
struct mg_mgr mgr; // Mongoose event manager
|
|
||||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // network interface
|
|
||||||
|
|
||||||
void mqtt_publish(const char *message) {
|
|
||||||
struct mg_mqtt_opts opts = {};
|
|
||||||
opts.topic = mg_str(mqtt_publish_topic);
|
|
||||||
opts.message = mg_str(message);
|
|
||||||
if (mqtt_connection) mg_mqtt_pub(mqtt_connection, &opts);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
if (ev == MG_EV_MQTT_OPEN) {
|
|
||||||
MG_INFO(("%lu CONNECTED to %s", c->id, MQTT_SERVER));
|
|
||||||
struct mg_mqtt_opts opts = {};
|
|
||||||
opts.topic = mg_str(mqtt_subscribe_topic);
|
|
||||||
mg_mqtt_sub(c, &opts);
|
|
||||||
MG_INFO(("%lu SUBSCRIBED to %s", c->id, mqtt_subscribe_topic));
|
|
||||||
} else if (ev == MG_EV_MQTT_MSG) {
|
|
||||||
// Received MQTT message
|
|
||||||
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
|
||||||
MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, (int) mm->data.len,
|
|
||||||
mm->data.buf, (int) mm->topic.len, mm->topic.buf));
|
|
||||||
exec_command(mm->data.buf, mm->data.len);
|
|
||||||
} else if (ev == MG_EV_CLOSE) {
|
|
||||||
MG_INFO(("%lu CLOSED", c->id));
|
|
||||||
mqtt_connection = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
struct mg_mgr *mgr = (struct mg_mgr *) arg;
|
|
||||||
struct mg_mqtt_opts opts;
|
|
||||||
memset(&opts, 0, sizeof(opts));
|
|
||||||
opts.clean = true;
|
|
||||||
if (mif.state == MG_TCPIP_STATE_READY && mqtt_connection == NULL) {
|
|
||||||
mqtt_connection = mg_mqtt_connect(mgr, MQTT_SERVER, &opts, fn, NULL);
|
|
||||||
}
|
|
||||||
// MG_INFO(("Eth: %d, MQTT: %p", mif.state, mqtt_connection));
|
|
||||||
}
|
|
||||||
|
|
||||||
void net_init(void) {
|
|
||||||
// Set Mongoose logging function to a serial print
|
|
||||||
mg_mgr_init(&mgr);
|
|
||||||
|
|
||||||
mif.driver = &mg_tcpip_driver_w5500;
|
|
||||||
mif.driver_data = &spi;
|
|
||||||
mg_tcpip_init(&mgr, &mif);
|
|
||||||
|
|
||||||
// Start a timer that keeps MQTT connection alive
|
|
||||||
mg_timer_add(&mgr, 3000, MG_TIMER_REPEAT, timer_fn, &mgr);
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "mongoose.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern struct mg_tcpip_spi spi;
|
|
||||||
extern struct mg_mgr mgr;
|
|
||||||
void mqtt_publish(const char *message);
|
|
||||||
void net_init(void);
|
|
||||||
void exec_command(const char *req, size_t req_len);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,51 +1,103 @@
|
|||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include "net.h"
|
#include "mongoose.h"
|
||||||
|
|
||||||
#define SS_PIN 17 // Slave select pin
|
#define MQTT_SERVER "mqtt://broker.hivemq.com:1883"
|
||||||
|
#define MQTT_SUB_TOPIC "mg/rx" // Subscribe to this topic
|
||||||
|
#define MQTT_PUB_TOPIC "mg/tx" // Publish to this topic
|
||||||
|
#define SS_PIN 2 // Slave select pin
|
||||||
|
#define LED_PIN 21 // LED pin
|
||||||
|
|
||||||
|
struct mg_connection *mqtt_connection;
|
||||||
struct mg_tcpip_spi spi = {
|
struct mg_tcpip_spi spi = {
|
||||||
NULL, // SPI data
|
NULL, // SPI metadata
|
||||||
[](void *) { digitalWrite(SS_PIN, LOW); }, // Begin transaction
|
[](void *) { digitalWrite(SS_PIN, LOW); SPI.beginTransaction(SPISettings()); },
|
||||||
[](void *) { digitalWrite(SS_PIN, HIGH); }, // End transaction
|
[](void *) { digitalWrite(SS_PIN, HIGH); SPI.endTransaction(); },
|
||||||
[](void *, uint8_t c) { return SPI.transfer(c); }, // Execute transaction
|
[](void *, uint8_t c) { return SPI.transfer(c); }, // Execute transaction
|
||||||
};
|
};
|
||||||
|
struct mg_mgr mgr; // Mongoose event manager
|
||||||
|
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // Network interface
|
||||||
|
|
||||||
void exec_command(const char *req, size_t req_len) {
|
uint64_t mg_millis(void) {
|
||||||
char res[100];
|
return millis();
|
||||||
if (req_len == 2 && strncmp(req, "on", req_len) == 0) {
|
}
|
||||||
digitalWrite(LED_BUILTIN, true);
|
bool mg_random(void *buf, size_t len) { // For TLS
|
||||||
snprintf(res, sizeof(res), "LED on");
|
uint8_t *p = (uint8_t *) buf;
|
||||||
} else if (req_len == 3 && strncmp(req, "off", req_len) == 0) {
|
while (len--) *p++ = (unsigned char) (rand() & 255);
|
||||||
digitalWrite(LED_BUILTIN, false);
|
return true;
|
||||||
snprintf(res, sizeof(res), "LED off");
|
|
||||||
} else {
|
|
||||||
snprintf(res, sizeof(res), "Unknown command: [%.*s]", (int) req_len, req);
|
|
||||||
}
|
|
||||||
Serial.println(res);
|
|
||||||
mqtt_publish(res);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_input(char c) {
|
void mqtt_publish(const char *message) {
|
||||||
static char buf[100];
|
struct mg_mqtt_opts opts = {};
|
||||||
static size_t len = 0;
|
opts.topic = mg_str(MQTT_PUB_TOPIC);
|
||||||
char response[100];
|
opts.message = mg_str(message);
|
||||||
if (c != '\n' && c != '\0') buf[len++] = c; // Append to the buffer
|
if (mqtt_connection) mg_mqtt_pub(mqtt_connection, &opts);
|
||||||
if (len >= sizeof(buf)) len = 0; // On overflow, reset
|
}
|
||||||
if (c == '\n' && len > 0) {
|
|
||||||
exec_command(buf, len);
|
// Crude function to get available RAM, for quick profiling
|
||||||
len = 0;
|
size_t getFreeRAM(void) {
|
||||||
|
size_t size = 0, increment = 100;
|
||||||
|
void *p;
|
||||||
|
while ((p = malloc(size)) != NULL) free(p), size += increment;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implement LED control over MQTT: "on" and "off" commands
|
||||||
|
void handle_command(struct mg_str msg) {
|
||||||
|
if (msg.len == 3 && memcmp(msg.buf, "off", 3) == 0) {
|
||||||
|
digitalWrite(LED_PIN, LOW);
|
||||||
|
mqtt_publish("done - off");
|
||||||
|
} else if (msg.len == 2 && memcmp(msg.buf, "on", 2) == 0) {
|
||||||
|
digitalWrite(LED_PIN, HIGH);
|
||||||
|
mqtt_publish("done - on");
|
||||||
|
}
|
||||||
|
MG_INFO(("Free RAM: %u bytes", getFreeRAM()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mqtt_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
if (ev == MG_EV_MQTT_OPEN) {
|
||||||
|
MG_INFO(("%lu CONNECTED to %s", c->id, MQTT_SERVER));
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.topic = mg_str(MQTT_SUB_TOPIC);
|
||||||
|
mg_mqtt_sub(c, &opts);
|
||||||
|
MG_INFO(("%lu SUBSCRIBED to %s", c->id, MQTT_SUB_TOPIC));
|
||||||
|
} else if (ev == MG_EV_MQTT_MSG) {
|
||||||
|
// Received MQTT message
|
||||||
|
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
|
||||||
|
MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, (int) mm->data.len,
|
||||||
|
mm->data.buf, (int) mm->topic.len, mm->topic.buf));
|
||||||
|
handle_command(mm->data);
|
||||||
|
} else if (ev == MG_EV_CLOSE) {
|
||||||
|
MG_INFO(("%lu CLOSED", c->id));
|
||||||
|
mqtt_connection = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reconnect_if_not_connected(void) {
|
||||||
|
if (mif.state == MG_TCPIP_STATE_READY && mqtt_connection == NULL) {
|
||||||
|
struct mg_mqtt_opts opts = {};
|
||||||
|
opts.clean = true;
|
||||||
|
mqtt_connection =
|
||||||
|
mg_mqtt_connect(&mgr, MQTT_SERVER, &opts, mqtt_ev_handler, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
Serial.begin(115200);
|
Serial.begin(115200); // Initialise serial
|
||||||
SPI.begin();
|
while (!Serial) delay(50); // for debug output
|
||||||
pinMode(SS_PIN, OUTPUT);
|
|
||||||
pinMode(LED_BUILTIN, OUTPUT);
|
SPI.begin(); // Iniitialise SPI
|
||||||
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
|
pinMode(SS_PIN, OUTPUT); // to communicate with W5500 Ethernet module
|
||||||
net_init();
|
pinMode(LED_PIN, OUTPUT); // Initialise LED
|
||||||
|
|
||||||
|
mg_mgr_init(&mgr); // Initialise Mongoose event manager
|
||||||
|
mg_log_set(MG_LL_DEBUG); // Set debug log level
|
||||||
|
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL); // Log serial
|
||||||
|
mif.driver = &mg_tcpip_driver_w5500; // Use W5500 built-in driver
|
||||||
|
mif.driver_data = &spi; // Pass SPI interface to W5500 driver
|
||||||
|
mg_tcpip_init(&mgr, &mif); // Initialise built-in TCP/IP stack
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
if (Serial.available()) process_input(Serial.read());
|
mg_mgr_poll(&mgr, 1); // Process network events
|
||||||
mg_mgr_poll(&mgr, 1);
|
reconnect_if_not_connected(); // Reconnect to MQTT server if needed
|
||||||
}
|
}
|
||||||
@@ -26,12 +26,6 @@ static struct settings s_settings = {true, 1, 57, NULL};
|
|||||||
static const char *s_json_header =
|
static const char *s_json_header =
|
||||||
"Content-Type: application/json\r\n"
|
"Content-Type: application/json\r\n"
|
||||||
"Cache-Control: no-cache\r\n";
|
"Cache-Control: no-cache\r\n";
|
||||||
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
|
|
||||||
// This is for newlib and TLS (mbedTLS)
|
|
||||||
uint64_t mg_now(void) {
|
|
||||||
return mg_millis() + s_boot_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ui_event_next(int no, struct ui_event *e) {
|
int ui_event_next(int no, struct ui_event *e) {
|
||||||
if (no < 0 || no >= MAX_EVENTS_NO) return 0;
|
if (no < 0 || no >= MAX_EVENTS_NO) return 0;
|
||||||
@@ -49,23 +43,8 @@ int ui_event_next(int no, struct ui_event *e) {
|
|||||||
return no + 1;
|
return no + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sfn(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
uint64_t *expiration_time = (uint64_t *) c->data;
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
|
||||||
} else if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = t - mg_millis();
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
static void timer_sntp_fn(void *param) { // SNTP timer function. Sync up time
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", sfn, NULL);
|
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse HTTP requests, return authenticated user or NULL
|
// Parse HTTP requests, return authenticated user or NULL
|
||||||
@@ -98,19 +77,22 @@ static struct user *authenticate(struct mg_http_message *hm) {
|
|||||||
|
|
||||||
static void handle_login(struct mg_connection *c, struct user *u) {
|
static void handle_login(struct mg_connection *c, struct user *u) {
|
||||||
char cookie[256];
|
char cookie[256];
|
||||||
|
const char *cookie_name = c->is_tls ? "secure_access_token" : "access_token";
|
||||||
mg_snprintf(cookie, sizeof(cookie),
|
mg_snprintf(cookie, sizeof(cookie),
|
||||||
"Set-Cookie: access_token=%s; Path=/; "
|
"Set-Cookie: %s=%s; Path=/; "
|
||||||
"%sHttpOnly; SameSite=Lax; Max-Age=%d\r\n",
|
"%sHttpOnly; SameSite=Lax; Max-Age=%d\r\n",
|
||||||
u->access_token, c->is_tls ? "Secure; " : "", 3600 * 24);
|
cookie_name, u->access_token,
|
||||||
|
c->is_tls ? "Secure; " : "", 3600 * 24);
|
||||||
mg_http_reply(c, 200, cookie, "{%m:%m}", MG_ESC("user"), MG_ESC(u->name));
|
mg_http_reply(c, 200, cookie, "{%m:%m}", MG_ESC("user"), MG_ESC(u->name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_logout(struct mg_connection *c) {
|
static void handle_logout(struct mg_connection *c) {
|
||||||
char cookie[256];
|
char cookie[256];
|
||||||
|
const char *cookie_name = c->is_tls ? "secure_access_token" : "access_token";
|
||||||
mg_snprintf(cookie, sizeof(cookie),
|
mg_snprintf(cookie, sizeof(cookie),
|
||||||
"Set-Cookie: access_token=; Path=/; "
|
"Set-Cookie: %s=; Path=/; "
|
||||||
"Expires=Thu, 01 Jan 1970 00:00:00 UTC; "
|
"Expires=Thu, 01 Jan 1970 00:00:00 UTC; "
|
||||||
"%sHttpOnly; Max-Age=0; \r\n",
|
"%sHttpOnly; Max-Age=0; \r\n", cookie_name,
|
||||||
c->is_tls ? "Secure; " : "");
|
c->is_tls ? "Secure; " : "");
|
||||||
mg_http_reply(c, 200, cookie, "true\n");
|
mg_http_reply(c, 200, cookie, "true\n");
|
||||||
}
|
}
|
||||||
@@ -217,49 +199,9 @@ static void handle_firmware_upload(struct mg_connection *c,
|
|||||||
mg_http_reply(c, 500, "", "mg_ota_end() failed\n", tot);
|
mg_http_reply(c, 500, "", "mg_ota_end() failed\n", tot);
|
||||||
} else {
|
} else {
|
||||||
mg_http_reply(c, 200, s_json_header, "true\n");
|
mg_http_reply(c, 200, s_json_header, "true\n");
|
||||||
if (data.len == 0) {
|
|
||||||
// Successful mg_ota_end() called, schedule device reboot
|
|
||||||
mg_timer_add(c->mgr, 500, 0, (void (*)(void *)) mg_device_reset, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_firmware_commit(struct mg_connection *c) {
|
|
||||||
mg_http_reply(c, 200, s_json_header, "%s\n",
|
|
||||||
mg_ota_commit() ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_firmware_rollback(struct mg_connection *c) {
|
|
||||||
mg_http_reply(c, 200, s_json_header, "%s\n",
|
|
||||||
mg_ota_rollback() ? "true" : "false");
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t print_status(void (*out)(char, void *), void *ptr, va_list *ap) {
|
|
||||||
int fw = va_arg(*ap, int);
|
|
||||||
return mg_xprintf(out, ptr, "{%m:%d,%m:%c%lx%c,%m:%u,%m:%u}\n",
|
|
||||||
MG_ESC("status"), mg_ota_status(fw), MG_ESC("crc32"), '"',
|
|
||||||
mg_ota_crc32(fw), '"', MG_ESC("size"), mg_ota_size(fw),
|
|
||||||
MG_ESC("timestamp"), mg_ota_timestamp(fw));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_firmware_status(struct mg_connection *c) {
|
|
||||||
mg_http_reply(c, 200, s_json_header, "[%M,%M]\n", print_status,
|
|
||||||
MG_FIRMWARE_CURRENT, print_status, MG_FIRMWARE_PREVIOUS);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_device_reset(struct mg_connection *c) {
|
|
||||||
mg_http_reply(c, 200, s_json_header, "true\n");
|
|
||||||
mg_timer_add(c->mgr, 500, 0, (void (*)(void *)) mg_device_reset, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_device_eraselast(struct mg_connection *c) {
|
|
||||||
size_t ss = mg_flash_sector_size(), size = mg_flash_size();
|
|
||||||
char *base = (char *) mg_flash_start(), *last = base + size - ss;
|
|
||||||
if (mg_flash_bank() == 2) last -= size / 2;
|
|
||||||
mg_flash_erase(last);
|
|
||||||
mg_http_reply(c, 200, s_json_header, "true\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// HTTP request handler function
|
// HTTP request handler function
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
if (ev == MG_EV_ACCEPT) {
|
if (ev == MG_EV_ACCEPT) {
|
||||||
@@ -291,16 +233,6 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
|||||||
handle_settings_set(c, hm->body);
|
handle_settings_set(c, hm->body);
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/firmware/upload"), NULL)) {
|
} else if (mg_match(hm->uri, mg_str("/api/firmware/upload"), NULL)) {
|
||||||
handle_firmware_upload(c, hm);
|
handle_firmware_upload(c, hm);
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/firmware/commit"), NULL)) {
|
|
||||||
handle_firmware_commit(c);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/firmware/rollback"), NULL)) {
|
|
||||||
handle_firmware_rollback(c);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/firmware/status"), NULL)) {
|
|
||||||
handle_firmware_status(c);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/device/reset"), NULL)) {
|
|
||||||
handle_device_reset(c);
|
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/device/eraselast"), NULL)) {
|
|
||||||
handle_device_eraselast(c);
|
|
||||||
} else {
|
} else {
|
||||||
struct mg_http_serve_opts opts;
|
struct mg_http_serve_opts opts;
|
||||||
memset(&opts, 0, sizeof(opts));
|
memset(&opts, 0, sizeof(opts));
|
||||||
|
|||||||
@@ -27,7 +27,15 @@ void app_main(void) {
|
|||||||
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
|
||||||
}
|
}
|
||||||
|
|
||||||
#if MG_DEVICE == MG_DEVICE_CUSTOM
|
#if MG_OTA == MG_OTA_CUSTOM
|
||||||
|
enum {
|
||||||
|
MG_OTA_UNAVAILABLE = 0, // No OTA information is present
|
||||||
|
MG_OTA_FIRST_BOOT = 1, // Device booting the first time after the OTA
|
||||||
|
MG_OTA_UNCOMMITTED = 2, // Ditto, but marking us for the rollback
|
||||||
|
MG_OTA_COMMITTED = 3 // The firmware is good
|
||||||
|
};
|
||||||
|
enum { MG_FIRMWARE_CURRENT = 0, MG_FIRMWARE_PREVIOUS = 1 };
|
||||||
|
|
||||||
void *mg_flash_start(void) {
|
void *mg_flash_start(void) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -57,9 +65,7 @@ bool mg_flash_write(void *addr, const void *buf, size_t len) {
|
|||||||
void mg_device_reset(void) {
|
void mg_device_reset(void) {
|
||||||
esp_restart();
|
esp_restart();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MG_OTA == MG_OTA_CUSTOM
|
|
||||||
#include "esp_app_format.h"
|
#include "esp_app_format.h"
|
||||||
#include "esp_ota_ops.h"
|
#include "esp_ota_ops.h"
|
||||||
|
|
||||||
@@ -121,6 +127,14 @@ bool check_fw_header(const void* buf, size_t len) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t mg_ota_size(int fw) {
|
||||||
|
const esp_partition_t *p = get_partition_from_fw(fw);
|
||||||
|
if (NULL == p) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return p->size;
|
||||||
|
}
|
||||||
|
|
||||||
bool mg_ota_begin(size_t new_firmware_size) {
|
bool mg_ota_begin(size_t new_firmware_size) {
|
||||||
rx_checked = false;
|
rx_checked = false;
|
||||||
if (s_size) {
|
if (s_size) {
|
||||||
@@ -255,11 +269,4 @@ uint32_t mg_ota_timestamp(int fw) {
|
|||||||
return mktime(&datetime);
|
return mktime(&datetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t mg_ota_size(int fw) {
|
|
||||||
const esp_partition_t *p = get_partition_from_fw(fw);
|
|
||||||
if (NULL == p) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return p->size;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
@@ -3,4 +3,3 @@
|
|||||||
#define MG_ENABLE_PACKED_FS 1
|
#define MG_ENABLE_PACKED_FS 1
|
||||||
#define MG_TLS MG_TLS_NONE // change to 'MG_TLS_MBED' to enable TLS
|
#define MG_TLS MG_TLS_NONE // change to 'MG_TLS_MBED' to enable TLS
|
||||||
#define MG_OTA MG_OTA_CUSTOM
|
#define MG_OTA MG_OTA_CUSTOM
|
||||||
#define MG_DEVICE MG_DEVICE_CUSTOM
|
|
||||||
@@ -1,41 +1,29 @@
|
|||||||
CFLAGS = -W -Wall -Werror -Wextra -Wundef -Wshadow -Wdouble-promotion
|
BOARD = xmc7200
|
||||||
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
|
IDE = GCC+make
|
||||||
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
|
RTOS = baremetal
|
||||||
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_xmc7/devices/COMPONENT_CAT1C/include/
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
CFLAGS += -Icmsis_xmc7/devices/COMPONENT_CAT1C/include/ip/
|
|
||||||
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 $(CFLAGS_EXTRA)
|
|
||||||
LDSCRIPT = link.ld
|
|
||||||
LDFLAGS ?= -T$(LDSCRIPT) -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
|
||||||
|
|
||||||
SOURCES = main.c hal.c startup.c
|
|
||||||
CFLAGS += -D__ATOLLIC__ -D__STARTUP_CLEAR_BSS # Make startup code work as expected
|
|
||||||
|
|
||||||
# Mongoose options are defined in mongoose_custom.h
|
|
||||||
SOURCES += mongoose.c net.c packed_fs.c
|
|
||||||
|
|
||||||
# Example specific build options. See README.md
|
|
||||||
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\"
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
|
||||||
RM = cmd /C del /Q /F /S
|
|
||||||
else
|
|
||||||
RM = rm -rf
|
|
||||||
endif
|
|
||||||
|
|
||||||
all build example: firmware.bin
|
all build example: firmware.bin
|
||||||
|
|
||||||
firmware.bin: firmware.elf
|
firmware.bin: wizard
|
||||||
arm-none-eabi-objcopy -O binary $< $@
|
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
|
||||||
|
|
||||||
firmware.elf: cmsis_core cmsis_xmc7 $(SOURCES) hal.h link.ld Makefile
|
wizard:
|
||||||
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
arm-none-eabi-size $@
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard ; rm mongoose.[ch] ; ln -s ../../../../mongoose.c ; ln -s ../../../../mongoose.h
|
||||||
|
|
||||||
cmsis_core: # ARM CMSIS core headers
|
|
||||||
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
cmsis_xmc7:
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/??
|
||||||
git clone https://github.com/Infineon/mtb-pdl-cat1.git $@
|
update: firmware.bin
|
||||||
echo "" > cmsis_xmc7/devices/COMPONENT_CAT1C/include/ip/system_cat1c.h
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
|
test update: CFLAGS_EXTRA ="-DUART_DEBUG=USART1"
|
||||||
|
test: update
|
||||||
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=15 | tee /tmp/output.txt
|
||||||
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) firmware.* *.su cmsis_core cmsis_xmc7 *.zip
|
rm -rf firmware.* wizard*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=xmc7200&ide=GCC+make&rtos=baremetal&file=README.md)
|
||||||
@@ -1,146 +0,0 @@
|
|||||||
// Copyright (c) 2024 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
static volatile uint64_t s_ticks; // Milliseconds since boot
|
|
||||||
void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
|
|
||||||
s_ticks++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
|
||||||
uint32_t r = rng_read();
|
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
|
||||||
return s_ticks; // Return number of milliseconds since boot
|
|
||||||
}
|
|
||||||
|
|
||||||
void hal_init(void) {
|
|
||||||
clock_init(); // Set system clock to SYS_FREQUENCY
|
|
||||||
SystemCoreClock = SYS_FREQUENCY; // Update SystemCoreClock global var
|
|
||||||
SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms
|
|
||||||
rng_init(); // Initialise random number generator
|
|
||||||
|
|
||||||
uart_init(UART_DEBUG, 115200); // Initialise UART
|
|
||||||
gpio_output(LED1); // Initialise LED1
|
|
||||||
gpio_output(LED2); // Initialise LED2
|
|
||||||
gpio_output(LED3); // Initialise LED3
|
|
||||||
ethernet_init(); // Initialise Ethernet pins
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__ARMCC_VERSION)
|
|
||||||
// Keil specific - implement IO printf redirection
|
|
||||||
int fputc(int c, FILE *stream) {
|
|
||||||
if (stream == stdout || stream == stderr) uart_write_byte(UART_DEBUG, c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
// ARM GCC specific. ARM GCC is shipped with Newlib C library.
|
|
||||||
// Implement newlib syscalls:
|
|
||||||
// _sbrk() for malloc
|
|
||||||
// _write() for printf redirection
|
|
||||||
// the rest are just stubs
|
|
||||||
#include <sys/stat.h> // For _fstat()
|
|
||||||
|
|
||||||
uint32_t SystemCoreClock;
|
|
||||||
void SystemInit(void) { // Called automatically by startup code
|
|
||||||
}
|
|
||||||
|
|
||||||
int _fstat(int fd, struct stat *st) {
|
|
||||||
(void) fd, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern unsigned char _end[]; // End of data section, start of heap. See link.ld
|
|
||||||
static unsigned char *s_current_heap_end = _end;
|
|
||||||
|
|
||||||
size_t hal_ram_used(void) {
|
|
||||||
return (size_t) (s_current_heap_end - _end);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t hal_ram_free(void) {
|
|
||||||
unsigned char endofstack;
|
|
||||||
return (size_t) (&endofstack - s_current_heap_end);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *_sbrk(int incr) {
|
|
||||||
unsigned char *prev_heap;
|
|
||||||
unsigned char *heap_end = (unsigned char *) ((size_t) &heap_end - 256);
|
|
||||||
prev_heap = s_current_heap_end;
|
|
||||||
// Check how much space we got from the heap end to the stack end
|
|
||||||
if (s_current_heap_end + incr > heap_end) return (void *) -1;
|
|
||||||
s_current_heap_end += incr;
|
|
||||||
return prev_heap;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _open(const char *path) {
|
|
||||||
(void) path;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _close(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isatty(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _lseek(int fd, int ptr, int dir) {
|
|
||||||
(void) fd, (void) ptr, (void) dir;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _exit(int status) {
|
|
||||||
(void) status;
|
|
||||||
for (;;) asm volatile("BKPT #0");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _kill(int pid, int sig) {
|
|
||||||
(void) pid, (void) sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getpid(void) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _write(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _read(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _link(const char *a, const char *b) {
|
|
||||||
(void) a, (void) b;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _unlink(const char *a) {
|
|
||||||
(void) a;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _stat(const char *path, struct stat *st) {
|
|
||||||
(void) path, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode) {
|
|
||||||
(void) path, (void) mode;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(void) {
|
|
||||||
}
|
|
||||||
#endif // __GNUC__
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define LED1 PIN(16, 1)
|
|
||||||
#define LED2 PIN(16, 2)
|
|
||||||
#define LED3 PIN(16, 3)
|
|
||||||
|
|
||||||
#include "xmc7200d_e272k8384.h"
|
|
||||||
|
|
||||||
#define BIT(x) (1UL << (x))
|
|
||||||
#define CLRSET(reg, clear, set) ((reg) = ((reg) & ~(clear)) | (set))
|
|
||||||
#define PIN(bank, num) ((bank << 8) | (num))
|
|
||||||
#define PINNO(pin) (pin & 255)
|
|
||||||
#define PINBANK(pin) (pin >> 8)
|
|
||||||
|
|
||||||
void hal_init(void);
|
|
||||||
size_t hal_ram_free(void);
|
|
||||||
size_t hal_ram_used(void);
|
|
||||||
|
|
||||||
static inline void spin(volatile uint32_t count) {
|
|
||||||
while (count--) (void) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern uint32_t SystemCoreClock;
|
|
||||||
|
|
||||||
enum {PLL_FEEDBACK = 50, PLL_REF = 1, PLL_OUT = 4};
|
|
||||||
#define CLK_IMO 8000000UL
|
|
||||||
#define SYS_FREQUENCY ((CLK_IMO * PLL_FEEDBACK) / (PLL_REF * PLL_OUT))
|
|
||||||
|
|
||||||
#ifndef UART_DEBUG
|
|
||||||
#define UART_DEBUG SCB3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT, GPIO_MODE_AF, GPIO_MODE_ANALOG };
|
|
||||||
enum { GPIO_HIGHZ = 0, GPIO_PULLUP = 2, GPIO_PULLDOWN = 3, GPIO_OPENDRAIN_LOW = 4,
|
|
||||||
GPIO_OPENDRAIN_HIGH = 5, GPIO_STRONG = 6, GPIO_PULLUP_DOWN = 7};
|
|
||||||
enum { GPIO_SPEED_LOW = 3, GPIO_SPEED_MEDIUM = 2, GPIO_SPEED_HIGH = 0};
|
|
||||||
#undef GPIO
|
|
||||||
#define GPIO_TypeDef GPIO_PRT_Type
|
|
||||||
#define GPIO(N) ((GPIO_TypeDef *) (GPIO_BASE + 0x80 * (N)))
|
|
||||||
|
|
||||||
static GPIO_TypeDef *gpio_bank(uint16_t pin) { return GPIO(PINBANK(pin)); }
|
|
||||||
|
|
||||||
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
|
|
||||||
uint8_t speed, uint8_t pull, uint8_t af) {
|
|
||||||
(void) pin, (void) mode, (void) type, (void) speed, (void) pull, (void) af;
|
|
||||||
GPIO_TypeDef *gpio = gpio_bank(pin);
|
|
||||||
uint8_t pinno = PINNO(pin);
|
|
||||||
uint32_t msk, pos;
|
|
||||||
|
|
||||||
// configure input / output direction
|
|
||||||
if (mode == GPIO_MODE_INPUT) {
|
|
||||||
gpio->CFG |= 1 << (4 * pinno + 3); // enable input buffer (IN_ENx)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (af || (mode == GPIO_MODE_AF && af)) {
|
|
||||||
// configure alternate function
|
|
||||||
HSIOM_PRT_Type* hsiom = ((HSIOM_PRT_Type*) HSIOM) + PINBANK(pin);
|
|
||||||
volatile uint32_t *port_sel = pinno < 4 ? &hsiom->PORT_SEL0 : &hsiom->PORT_SEL1;
|
|
||||||
pos = 8 * (pinno % 4), msk = 0x1f << pos;
|
|
||||||
*port_sel &= ~msk, *port_sel |= af << pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure driver mode
|
|
||||||
msk = 7, pos = 4 * pinno;
|
|
||||||
CLRSET(gpio->CFG, msk << pos, type << pos);
|
|
||||||
|
|
||||||
// configure speed
|
|
||||||
msk = 3, pos = 2 * pinno + 16;
|
|
||||||
CLRSET(gpio->CFG_OUT, msk << pos, speed << pos);
|
|
||||||
|
|
||||||
if (mode == GPIO_MODE_OUTPUT /*&& af == 0*/) {
|
|
||||||
gpio->OUT_SET = (1 << pinno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_input(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH,
|
|
||||||
0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_output(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_MEDIUM,
|
|
||||||
0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool gpio_read(uint16_t pin) {
|
|
||||||
GPIO_TypeDef *gpio = gpio_bank(pin);
|
|
||||||
uint8_t pinno = PINNO(pin);
|
|
||||||
if (gpio->CFG & (1 << (4 * pinno + 3))) {
|
|
||||||
// pin mode is input, reading from GPIO_PRT_IN
|
|
||||||
return gpio->IN & (1 << pinno);
|
|
||||||
} else {
|
|
||||||
// pin mode is output, reading from GPIO_PRT_OUT
|
|
||||||
return gpio->OUT & (1 << pinno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_write(uint16_t pin, bool value) {
|
|
||||||
GPIO_TypeDef *gpio = gpio_bank(pin);
|
|
||||||
uint8_t pinno = PINNO(pin);
|
|
||||||
if (value) {
|
|
||||||
gpio->OUT_SET = 1 << pinno;
|
|
||||||
} else {
|
|
||||||
gpio->OUT_CLR = 1 << pinno;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_toggle(uint16_t pin) {
|
|
||||||
gpio_write(pin, !gpio_read(pin));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void uart_init(volatile CySCB_Type *uart, unsigned long baud) {
|
|
||||||
(void) uart, (void) baud;
|
|
||||||
uint16_t rx = 0, tx = 0;
|
|
||||||
if (uart == SCB3) {
|
|
||||||
rx = PIN(13, 0), tx = PIN(13, 1);
|
|
||||||
} else {
|
|
||||||
return; // unsupported uart
|
|
||||||
}
|
|
||||||
|
|
||||||
// set pins
|
|
||||||
gpio_init(rx, GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 17);
|
|
||||||
gpio_init(tx, GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_HIGH, 0, 17);
|
|
||||||
|
|
||||||
// enable peripheral clock (18.6.2)
|
|
||||||
// compute divider first (we choose 24 bit divider 0)
|
|
||||||
unsigned long div = 0, frac = 0, ovs = 16;
|
|
||||||
div = SYS_FREQUENCY / (baud * ovs);
|
|
||||||
if (div == 0) div = 1;
|
|
||||||
frac = SYS_FREQUENCY % (baud * ovs);
|
|
||||||
frac = (frac * 100) / (baud * ovs);
|
|
||||||
PERI_PCLK->GR[1].DIV_CMD = (3 << PERI_PCLK_GR_DIV_CMD_TYPE_SEL_Pos) |
|
|
||||||
PERI_PCLK_GR_DIV_CMD_PA_DIV_SEL_Msk |
|
|
||||||
PERI_PCLK_GR_DIV_CMD_PA_TYPE_SEL_Msk;
|
|
||||||
PERI_PCLK->GR[1].DIV_CMD |= PERI_PCLK_GR_DIV_CMD_DISABLE_Msk; // disable divider
|
|
||||||
PERI_PCLK->GR[1].DIV_24_5_CTL[0] = (((uint8_t) (div - 1)) << PERI_PCLK_GR_DIV_24_5_CTL_INT24_DIV_Pos) |
|
|
||||||
(frac << PERI_PCLK_GR_DIV_24_5_CTL_FRAC5_DIV_Pos);
|
|
||||||
PERI_PCLK->GR[1].DIV_CMD = (3 << PERI_PCLK_GR_DIV_CMD_TYPE_SEL_Pos) |
|
|
||||||
PERI_PCLK_GR_DIV_CMD_PA_DIV_SEL_Msk |
|
|
||||||
PERI_PCLK_GR_DIV_CMD_PA_TYPE_SEL_Msk;;
|
|
||||||
PERI_PCLK->GR[1].DIV_CMD |= PERI_PCLK_GR_DIV_CMD_ENABLE_Msk; // enable divider
|
|
||||||
PERI_PCLK->GR[1].CLOCK_CTL[PCLK_SCB3_CLOCK & 0xff] = 3 << PERI_PCLK_GR_CLOCK_CTL_TYPE_SEL_Pos; // connect SCB3 to div_24_5_ctl[0]
|
|
||||||
|
|
||||||
// configure UART interface
|
|
||||||
uart->CTRL = ((ovs - 1) << SCB_CTRL_OVS_Pos) | (2 << SCB_CTRL_MODE_Pos);
|
|
||||||
uart->UART_CTRL = 0;
|
|
||||||
uart->UART_RX_CTRL = 1 << SCB_UART_RX_CTRL_STOP_BITS_Pos;
|
|
||||||
uart->RX_CTRL = 7 << SCB_RX_CTRL_DATA_WIDTH_Pos;
|
|
||||||
uart->UART_TX_CTRL = 1 << SCB_UART_TX_CTRL_STOP_BITS_Pos;
|
|
||||||
uart->TX_CTRL = 7 << SCB_TX_CTRL_DATA_WIDTH_Pos;
|
|
||||||
uart->TX_FIFO_CTRL = 1 << 16;
|
|
||||||
uart->TX_FIFO_CTRL = 0;
|
|
||||||
uart->CTRL |= 1 << SCB_CTRL_ENABLED_Pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void uart_write_byte(volatile CySCB_Type *uart, uint8_t byte) {
|
|
||||||
(void) byte; (void) uart;
|
|
||||||
while((uart->INTR_TX & SCB_INTR_TX_EMPTY_Msk) == 0) spin(1);
|
|
||||||
uart->TX_FIFO_WR = byte;
|
|
||||||
uart->INTR_TX |= ~SCB_INTR_TX_EMPTY_Msk;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void uart_write_buf(volatile CySCB_Type *uart, char *buf, size_t len) {
|
|
||||||
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rng_init(void) {
|
|
||||||
}
|
|
||||||
static inline uint32_t rng_read(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void ethernet_init(void) {
|
|
||||||
gpio_init(PIN(26, 0), GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 27); // ETH1_REF_CLK
|
|
||||||
gpio_init(PIN(26, 1), GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_HIGH, 0, 27); // ETH1_TX_CTL
|
|
||||||
gpio_init(PIN(26, 2), GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_HIGH, 0, 27); // ETH1_TX_CLK
|
|
||||||
gpio_init(PIN(26, 3), GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_HIGH, 0, 27); // ETH1_TXD_0
|
|
||||||
gpio_init(PIN(26, 4), GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_HIGH, 0, 27); // ETH1_TXD_1
|
|
||||||
gpio_init(PIN(26, 5), GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_HIGH, 0, 27); // ETH1_TXD_2
|
|
||||||
gpio_init(PIN(26, 6), GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_HIGH, 0, 27); // ETH1_TXD_3
|
|
||||||
gpio_init(PIN(26, 7), GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 27); // ETH1_RXD_0
|
|
||||||
|
|
||||||
gpio_init(PIN(27, 0), GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 27); // ETH1_RXD_1
|
|
||||||
gpio_init(PIN(27, 1), GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 27); // ETH1_RXD_2
|
|
||||||
gpio_init(PIN(27, 2), GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 27); // ETH1_RXD_3
|
|
||||||
gpio_init(PIN(27, 3), GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 27); // ETH1_RX_CTL
|
|
||||||
gpio_init(PIN(27, 4), GPIO_MODE_INPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 27); // ETH1_RX_CLK
|
|
||||||
gpio_init(PIN(27, 5), GPIO_MODE_INPUT, GPIO_STRONG, GPIO_SPEED_LOW, 0, 27); // ETH1_MDIO
|
|
||||||
gpio_init(PIN(27, 6), GPIO_MODE_OUTPUT, GPIO_STRONG, GPIO_SPEED_LOW, 0, 27); // ETH1_MDC
|
|
||||||
//gpio_init(PIN(27, 7), GPIO_MODE_OUTPUT, GPIO_HIGHZ, GPIO_SPEED_HIGH, 0, 0); // ETH1_RST
|
|
||||||
|
|
||||||
CPUSS->CM7_0_SYSTEM_INT_CTL[eth_1_interrupt_eth_0_IRQn] = 0x80000003; // assign CPU interrupt #3
|
|
||||||
NVIC->ISER[0] = 1 << 3;
|
|
||||||
|
|
||||||
spin(10000000); // artificial delay to wait for PHY init
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void clock_init(void) {
|
|
||||||
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU
|
|
||||||
asm("DSB");
|
|
||||||
asm("ISB");
|
|
||||||
|
|
||||||
// configure PLL
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG, CLK_PLL400M_CONFIG_BYPASS_SEL_Msk, BIT(29)); // First bypass PLL
|
|
||||||
spin(10);
|
|
||||||
SRSS->CLK_PLL400M[0].CONFIG &= ~CLK_PLL400M_CONFIG_ENABLE_Msk; // disable the PLL itself
|
|
||||||
|
|
||||||
// IMO source generates a frequency of 8MHz. The final frequency will be
|
|
||||||
// calculated as (CLK_IMO * feedback) / (reference * output_div)
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG, CLK_PLL400M_CONFIG_FEEDBACK_DIV_Msk, PLL_FEEDBACK << CLK_PLL400M_CONFIG_FEEDBACK_DIV_Pos);
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG, CLK_PLL400M_CONFIG_REFERENCE_DIV_Msk, PLL_REF << CLK_PLL400M_CONFIG_REFERENCE_DIV_Pos);
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG, CLK_PLL400M_CONFIG_OUTPUT_DIV_Msk, PLL_OUT << CLK_PLL400M_CONFIG_OUTPUT_DIV_Pos);
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG2, CLK_PLL400M_CONFIG2_FRAC_DIV_Msk, 0);
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG2, CLK_PLL400M_CONFIG2_FRAC_DITHER_EN_Msk, 0);
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG2, CLK_PLL400M_CONFIG2_FRAC_EN_Msk, 1 << CLK_PLL400M_CONFIG2_FRAC_EN_Pos);
|
|
||||||
CLRSET(SRSS->CLK_PLL400M[0].CONFIG, CLK_PLL400M_CONFIG_BYPASS_SEL_Msk, 0);
|
|
||||||
spin(10);
|
|
||||||
SRSS->CLK_PLL400M[0].CONFIG |= CLK_PLL400M_CONFIG_ENABLE_Msk; // enable the PLL
|
|
||||||
while (SRSS->CLK_PLL400M[0].CONFIG & 1) spin(1);
|
|
||||||
|
|
||||||
// configure PATH1 with source set to IMO
|
|
||||||
SRSS->CLK_PATH_SELECT[1] = 0;
|
|
||||||
|
|
||||||
// enable CLK_HFx
|
|
||||||
uint8_t clocks[] = {0, 1, 2, 3, 4, 5, 6};
|
|
||||||
for (size_t i = 0; i < sizeof(clocks) / sizeof(uint8_t); i++) {
|
|
||||||
CLRSET(SRSS->CLK_ROOT_SELECT[clocks[i]], SRSS_CLK_ROOT_SELECT_ROOT_MUX_Msk, 1); // choose PATH1
|
|
||||||
CLRSET(SRSS->CLK_ROOT_SELECT[clocks[i]], SRSS_CLK_ROOT_SELECT_DIRECT_MUX_Msk, 1 << SRSS_CLK_ROOT_SELECT_DIRECT_MUX_Pos);
|
|
||||||
if (clocks[i] != 0) // CLF_HF0 is already enabled
|
|
||||||
SRSS->CLK_ROOT_SELECT[clocks[i]] |= SRSS_CLK_ROOT_SELECT_ENABLE_Msk; // enable clock root
|
|
||||||
}
|
|
||||||
|
|
||||||
// set systick frequency
|
|
||||||
uint32_t tenms = SYS_FREQUENCY / 100 - 1; // number of cycles executed in 10ms
|
|
||||||
CPUSS->SYSTICK_CTL = tenms | (3 << CPUSS_SYSTICK_CTL_CLOCK_SOURCE_Pos); // select CLK_HF as source
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
OUTPUT_FORMAT("elf32-littlearm")
|
|
||||||
OUTPUT_ARCH(arm)
|
|
||||||
ENTRY(Reset_Handler)
|
|
||||||
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
flash(RX) : ORIGIN = 0x10080000, LENGTH = 0x80000
|
|
||||||
sram(!RX) : ORIGIN = 0x28000800, LENGTH = 510K
|
|
||||||
}
|
|
||||||
|
|
||||||
_estack = ORIGIN(sram) + LENGTH(sram);
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.vectors : { . = ALIGN(4); KEEP(*(.vectors)); . = ALIGN(4); } > flash
|
|
||||||
.text : { *(.text*) } > flash
|
|
||||||
.rodata : { *(.rodata*) } > flash
|
|
||||||
|
|
||||||
.data : {
|
|
||||||
_sdata = .;
|
|
||||||
*(.first_data)
|
|
||||||
*(.data SORT(.data.*))
|
|
||||||
_edata = .;
|
|
||||||
} > sram AT > flash
|
|
||||||
_sidata = LOADADDR(.data);
|
|
||||||
|
|
||||||
.bss : { _sbss = .; *(.bss SORT(.bss.*) COMMON) _ebss = .; } > sram
|
|
||||||
|
|
||||||
. = ALIGN(8);
|
|
||||||
_end = .;
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
// Copyright (c) 2024 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "mongoose.h"
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#define BLINK_PERIOD_MS 1000
|
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
gpio_toggle(LED1); // Blink LED
|
|
||||||
(void) arg; // Unused
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
struct mg_mgr mgr; // Mongoose event manager
|
|
||||||
|
|
||||||
hal_init(); // Cross-platform hardware init
|
|
||||||
|
|
||||||
mg_mgr_init(&mgr); // Initialise it
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level to debug
|
|
||||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mgr);
|
|
||||||
|
|
||||||
MG_INFO(("Initialising application..."));
|
|
||||||
web_init(&mgr);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
mg_mgr_poll(&mgr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// See https://mongoose.ws/documentation/#build-options
|
|
||||||
#define MG_ARCH MG_ARCH_NEWLIB
|
|
||||||
|
|
||||||
#define MG_ENABLE_TCPIP 1
|
|
||||||
#define MG_ENABLE_DRIVER_XMC7 1
|
|
||||||
#define MG_IO_SIZE 256
|
|
||||||
#define MG_ENABLE_CUSTOM_MILLIS 1
|
|
||||||
#define MG_ENABLE_CUSTOM_RANDOM 1
|
|
||||||
#define MG_ENABLE_PACKED_FS 1
|
|
||||||
|
|
||||||
// For static IP configuration, define MG_TCPIP_{IP,MASK,GW}
|
|
||||||
// By default, those are set to zero, meaning that DHCP is used
|
|
||||||
//
|
|
||||||
// #define MG_TCPIP_IP MG_IPV4(192, 168, 1, 10)
|
|
||||||
// #define MG_TCPIP_GW MG_IPV4(192, 168, 1, 1)
|
|
||||||
// #define MG_TCPIP_MASK MG_IPV4(255, 255, 255, 0)
|
|
||||||
|
|
||||||
// Set custom MAC address. By default, it is randomly generated
|
|
||||||
// Using a build-time constant:
|
|
||||||
// #define MG_SET_MAC_ADDRESS(mac) do { uint8_t buf_[6] = {2,3,4,5,6,7}; memmove(mac, buf_, sizeof(buf_)); } while (0)
|
|
||||||
//
|
|
||||||
// Using custom function:
|
|
||||||
// extern void my_function(unsigned char *mac);
|
|
||||||
// #define MG_SET_MAC_ADDRESS(mac) my_function(mac)
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
#include "xmc7200d_e272k8384.h"
|
|
||||||
|
|
||||||
void Reset_Handler(void); // Defined below
|
|
||||||
void Dummy_Handler(void); // Defined below
|
|
||||||
void SysTick_Handler(void); // Defined in main.c
|
|
||||||
void SystemInit(void); // Defined in main.c, called by reset handler
|
|
||||||
void _estack(void); // Defined in link.ld
|
|
||||||
|
|
||||||
#define WEAK_ALIAS __attribute__((weak, alias("Default_Handler")))
|
|
||||||
|
|
||||||
WEAK_ALIAS void NMI_Handler(void);
|
|
||||||
WEAK_ALIAS void HardFault_Handler(void);
|
|
||||||
WEAK_ALIAS void SVCall_Handler(void);
|
|
||||||
WEAK_ALIAS void PendSV_Handler(void);
|
|
||||||
WEAK_ALIAS void SysTick_Handler(void);
|
|
||||||
|
|
||||||
WEAK_ALIAS void Default_Intr_Handler(void);
|
|
||||||
WEAK_ALIAS void CM0P_CpuIntr0_Handler(void);
|
|
||||||
WEAK_ALIAS void CM0P_CpuIntr1_Handler(void);
|
|
||||||
WEAK_ALIAS void CM0P_CpuIntr2_Handler(void);
|
|
||||||
WEAK_ALIAS void CM0P_CpuIntr4_Handler(void);
|
|
||||||
WEAK_ALIAS void CM0P_CpuIntr5_Handler(void);
|
|
||||||
WEAK_ALIAS void CM0P_CpuIntr6_Handler(void);
|
|
||||||
WEAK_ALIAS void CM0P_CpuIntr7_Handler(void);
|
|
||||||
WEAK_ALIAS void ETH_IRQHandler(void);
|
|
||||||
|
|
||||||
void CM0P_CpuIntr3_Handler(void) {
|
|
||||||
ETH_IRQHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((section(".vectors"))) void (*const tab[16 + 16])(void) = {
|
|
||||||
_estack,
|
|
||||||
Reset_Handler,
|
|
||||||
NMI_Handler,
|
|
||||||
HardFault_Handler,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
SVCall_Handler,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
PendSV_Handler,
|
|
||||||
SysTick_Handler,
|
|
||||||
CM0P_CpuIntr0_Handler,
|
|
||||||
CM0P_CpuIntr1_Handler,
|
|
||||||
CM0P_CpuIntr2_Handler,
|
|
||||||
CM0P_CpuIntr3_Handler,
|
|
||||||
CM0P_CpuIntr4_Handler,
|
|
||||||
CM0P_CpuIntr5_Handler,
|
|
||||||
CM0P_CpuIntr6_Handler,
|
|
||||||
CM0P_CpuIntr7_Handler,
|
|
||||||
Default_Intr_Handler,
|
|
||||||
Default_Intr_Handler,
|
|
||||||
Default_Intr_Handler,
|
|
||||||
Default_Intr_Handler,
|
|
||||||
Default_Intr_Handler,
|
|
||||||
Default_Intr_Handler,
|
|
||||||
Default_Intr_Handler,
|
|
||||||
Default_Intr_Handler
|
|
||||||
};
|
|
||||||
|
|
||||||
__attribute__((naked, noreturn)) void Reset_Handler(void) {
|
|
||||||
// Clear BSS section, and copy data section from flash to RAM
|
|
||||||
extern long _sbss, _ebss, _sdata, _edata, _sidata;
|
|
||||||
for (long *src = &_sbss; src < &_ebss; src++) *src = 0;
|
|
||||||
for (long *src = &_sdata, *dst = &_sidata; src < &_edata;) *src++ = *dst++;
|
|
||||||
|
|
||||||
SCB->VTOR = (uint32_t) &tab;
|
|
||||||
SystemInit();
|
|
||||||
|
|
||||||
// Call main()
|
|
||||||
extern void main(void);
|
|
||||||
main();
|
|
||||||
for (;;) (void) 0; // Infinite loop
|
|
||||||
}
|
|
||||||
|
|
||||||
void Default_Handler(void) {
|
|
||||||
for (;;) (void) 0;
|
|
||||||
}
|
|
||||||
@@ -36,7 +36,7 @@ flash: firmware.bin
|
|||||||
cmsis_core:
|
cmsis_core:
|
||||||
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
||||||
cmsis_sam:
|
cmsis_sam:
|
||||||
curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.8.234.pack -o $@.zip
|
curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.9.244.atpack -o $@.zip
|
||||||
mkdir $@ && cd $@ && unzip ../$@.zip
|
mkdir $@ && cd $@ && unzip ../$@.zip
|
||||||
|
|
||||||
# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL
|
# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
|||||||
return s_ticks; // Return number of milliseconds since boot
|
return s_ticks; // Return number of milliseconds since boot
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
bool mg_random(void *buf, size_t len) { // Use on-board RNG
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
||||||
uint32_t r = rng_read();
|
uint32_t r = rng_read();
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
static void timer_fn(void *arg) {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ flash: firmware.bin
|
|||||||
cmsis_core:
|
cmsis_core:
|
||||||
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
||||||
cmsis_sam:
|
cmsis_sam:
|
||||||
curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.8.234.pack -o $@.zip
|
curl -sL https://packs.download.microchip.com/Microchip.SAME54_DFP.3.9.244.atpack -o $@.zip
|
||||||
mkdir $@ && cd $@ && unzip ../$@.zip
|
mkdir $@ && cd $@ && unzip ../$@.zip
|
||||||
|
|
||||||
# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL
|
# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL
|
||||||
|
|||||||
@@ -24,11 +24,12 @@ uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
|||||||
return s_ticks; // Return number of milliseconds since boot
|
return s_ticks; // Return number of milliseconds since boot
|
||||||
}
|
}
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
bool mg_random(void *buf, size_t len) { // Use on-board RNG
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
||||||
uint32_t r = rng_read();
|
uint32_t r = rng_read();
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ static struct device_settings s_settings;
|
|||||||
static const char *s_json_header =
|
static const char *s_json_header =
|
||||||
"Content-Type: application/json\r\n"
|
"Content-Type: application/json\r\n"
|
||||||
"Cache-Control: no-cache\r\n";
|
"Cache-Control: no-cache\r\n";
|
||||||
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
|
|
||||||
static void set_default_settings(struct device_settings *s) {
|
static void set_default_settings(struct device_settings *s) {
|
||||||
s->magic = SETTINGS_MAGIC;
|
s->magic = SETTINGS_MAGIC;
|
||||||
@@ -33,29 +32,9 @@ static void set_default_settings(struct device_settings *s) {
|
|||||||
mg_snprintf(s->mqtt_topic_rx, sizeof(s->mqtt_topic_rx), "%s", "modbus1/rx");
|
mg_snprintf(s->mqtt_topic_rx, sizeof(s->mqtt_topic_rx), "%s", "modbus1/rx");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is for newlib and TLS (mbedTLS)
|
|
||||||
uint64_t mg_now(void) {
|
|
||||||
return mg_millis() + s_boot_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sfn(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
uint64_t *expiration_time = (uint64_t *) c->data;
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
|
||||||
} else if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = t - mg_millis();
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SNTP timer function. Sync up time
|
// SNTP timer function. Sync up time
|
||||||
static void timer_sntp_fn(void *param) {
|
static void timer_sntp_fn(void *param) {
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", sfn, NULL);
|
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setfromjson(struct mg_str json, const char *jsonpath, char *buf,
|
static void setfromjson(struct mg_str json, const char *jsonpath, char *buf,
|
||||||
@@ -262,7 +241,6 @@ static void fn(struct mg_connection *c, int ev, void *ev_data) {
|
|||||||
} else if (mg_match(hm->uri, mg_str("/api/modbus/exec"), NULL)) {
|
} else if (mg_match(hm->uri, mg_str("/api/modbus/exec"), NULL)) {
|
||||||
handle_modbus_exec(c, hm->body);
|
handle_modbus_exec(c, hm->body);
|
||||||
} else if (mg_match(hm->uri, mg_str("/api/device/reset"), NULL)) {
|
} else if (mg_match(hm->uri, mg_str("/api/device/reset"), NULL)) {
|
||||||
mg_timer_add(c->mgr, 500, 0, (void (*)(void *)) mg_device_reset, NULL);
|
|
||||||
mg_http_reply(c, 200, s_json_header, "true\n");
|
mg_http_reply(c, 200, s_json_header, "true\n");
|
||||||
} else {
|
} else {
|
||||||
struct mg_http_serve_opts opts;
|
struct mg_http_serve_opts opts;
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
PWD := $(shell pwd)
|
all:
|
||||||
NPX ?= npx
|
make -C ../../../tutorials/http/http-server ARGS="-d $(CURDIR)"
|
||||||
|
|
||||||
all: bundle.js main.css
|
|
||||||
make -C ../../../tutorials/http/http-server ARGS="-d $(PWD)"
|
|
||||||
|
|
||||||
# Bundle JS libraries (preact, preact-router, ...) into a single file
|
# Bundle JS libraries (preact, preact-router, ...) into a single file
|
||||||
bundle.js:
|
bundle.js:
|
||||||
curl -s https://npm.reversehttp.com/preact,preact/hooks,htm/preact,preact-router -o $@
|
curl -s https://npm.reversehttp.com/preact,preact/hooks,htm/preact,preact-router -o $@
|
||||||
|
|
||||||
# Create optimised CSS. Prerequisite: npm -g i tailwindcss tailwindcss-font-inter
|
# Create optimised CSS. Prerequisite: npm -g i tailwindcss tailwindcss-font-inter
|
||||||
|
NPX ?= npx
|
||||||
main.css: index.html $(wildcard *.js)
|
main.css: index.html $(wildcard *.js)
|
||||||
$(NPX) tailwindcss -o $@ --minify
|
$(NPX) tailwindcss -o $@ --minify
|
||||||
|
|
||||||
|
|||||||
@@ -20,11 +20,6 @@ struct device_config {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct device_config s_device_config;
|
static struct device_config s_device_config;
|
||||||
static uint64_t s_boot_timestamp = 0; // Updated by SNTP
|
|
||||||
|
|
||||||
uint64_t mg_now(void) {
|
|
||||||
return mg_millis() + s_boot_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Device ID generation function. Create an ID that is unique
|
// Device ID generation function. Create an ID that is unique
|
||||||
// for a given device, and does not change between device restarts.
|
// for a given device, and does not change between device restarts.
|
||||||
@@ -58,15 +53,6 @@ static void set_device_id(void) {
|
|||||||
g_device_id = strdup(buf);
|
g_device_id = strdup(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t print_fw_status(void (*out)(char, void *), void *ptr,
|
|
||||||
va_list *ap) {
|
|
||||||
int fw = va_arg(*ap, int);
|
|
||||||
return mg_xprintf(out, ptr, "{%m:%d,%m:%c%lx%c,%m:%u,%m:%u}",
|
|
||||||
MG_ESC("status"), mg_ota_status(fw), MG_ESC("crc32"), '"',
|
|
||||||
mg_ota_crc32(fw), '"', MG_ESC("size"), mg_ota_size(fw),
|
|
||||||
MG_ESC("timestamp"), mg_ota_timestamp(fw));
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t print_shorts(void (*out)(char, void *), void *ptr, va_list *ap) {
|
static size_t print_shorts(void (*out)(char, void *), void *ptr, va_list *ap) {
|
||||||
uint16_t *array = va_arg(*ap, uint16_t *);
|
uint16_t *array = va_arg(*ap, uint16_t *);
|
||||||
int i, len = 0, num_elems = va_arg(*ap, int);
|
int i, len = 0, num_elems = va_arg(*ap, int);
|
||||||
@@ -92,7 +78,7 @@ static void publish_status(struct mg_connection *c) {
|
|||||||
|
|
||||||
// Print JSON notification into the io buffer
|
// Print JSON notification into the io buffer
|
||||||
mg_xprintf(mg_pfn_iobuf, &io,
|
mg_xprintf(mg_pfn_iobuf, &io,
|
||||||
"{%m:%m,%m:{%m:%m,%m:%d,%m:%d,%m:[%M],%m:[%M],%m:%M,%m:%M}}", //
|
"{%m:%m,%m:{%m:%m,%m:%d,%m:%d,%m:[%M],%m:[%M]}}", //
|
||||||
MG_ESC("method"), MG_ESC("status.notify"), MG_ESC("params"), //
|
MG_ESC("method"), MG_ESC("status.notify"), MG_ESC("params"), //
|
||||||
MG_ESC("status"), MG_ESC("online"), //
|
MG_ESC("status"), MG_ESC("online"), //
|
||||||
MG_ESC(("log_level")), s_device_config.log_level, //
|
MG_ESC(("log_level")), s_device_config.log_level, //
|
||||||
@@ -100,9 +86,7 @@ static void publish_status(struct mg_connection *c) {
|
|||||||
MG_ESC(("pin_map")), print_shorts, s_device_config.pin_map,
|
MG_ESC(("pin_map")), print_shorts, s_device_config.pin_map,
|
||||||
s_device_config.pin_count, //
|
s_device_config.pin_count, //
|
||||||
MG_ESC(("pin_state")), print_bools, s_device_config.pin_state,
|
MG_ESC(("pin_state")), print_bools, s_device_config.pin_state,
|
||||||
s_device_config.pin_count, //
|
s_device_config.pin_count);
|
||||||
MG_ESC(("crnt_fw")), print_fw_status, MG_FIRMWARE_CURRENT, //
|
|
||||||
MG_ESC(("prev_fw")), print_fw_status, MG_FIRMWARE_PREVIOUS);
|
|
||||||
|
|
||||||
memset(&pub_opts, 0, sizeof(pub_opts));
|
memset(&pub_opts, 0, sizeof(pub_opts));
|
||||||
mg_snprintf(topic, sizeof(topic), "%s/%s/status", g_root_topic, g_device_id);
|
mg_snprintf(topic, sizeof(topic), "%s/%s/status", g_root_topic, g_device_id);
|
||||||
@@ -165,27 +149,6 @@ static void rpc_config_set(struct mg_rpc_req *r) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpc_ota_commit(struct mg_rpc_req *r) {
|
|
||||||
if (mg_ota_commit()) {
|
|
||||||
mg_rpc_ok(r, "%m", MG_ESC("ok"));
|
|
||||||
} else {
|
|
||||||
mg_rpc_err(r, 1, "Failed to commit the firmware");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rpc_device_reset(struct mg_rpc_req *r) {
|
|
||||||
mg_rpc_ok(r, "%m", MG_ESC("ok"));
|
|
||||||
mg_timer_add(s_conn->mgr, 500, 0, (void (*)(void *)) mg_device_reset, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rpc_ota_rollback(struct mg_rpc_req *r) {
|
|
||||||
if (mg_ota_rollback()) {
|
|
||||||
mg_rpc_ok(r, "%m", MG_ESC("ok"));
|
|
||||||
} else {
|
|
||||||
mg_rpc_err(r, 1, "Failed to rollback to the previous firmware");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rpc_ota_upload(struct mg_rpc_req *r) {
|
static void rpc_ota_upload(struct mg_rpc_req *r) {
|
||||||
long ofs = mg_json_get_long(r->frame, "$.params.offset", -1);
|
long ofs = mg_json_get_long(r->frame, "$.params.offset", -1);
|
||||||
long tot = mg_json_get_long(r->frame, "$.params.total", -1);
|
long tot = mg_json_get_long(r->frame, "$.params.total", -1);
|
||||||
@@ -205,10 +168,6 @@ static void rpc_ota_upload(struct mg_rpc_req *r) {
|
|||||||
mg_rpc_err(r, 1, "mg_ota_end() failed\n", tot);
|
mg_rpc_err(r, 1, "mg_ota_end() failed\n", tot);
|
||||||
} else {
|
} else {
|
||||||
mg_rpc_ok(r, "%m", MG_ESC("ok"));
|
mg_rpc_ok(r, "%m", MG_ESC("ok"));
|
||||||
if (len == 0) { // Successful mg_ota_end() called, schedule device reboot
|
|
||||||
mg_timer_add(s_conn->mgr, 500, 0, (void (*)(void *)) mg_device_reset,
|
|
||||||
NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
@@ -277,26 +236,11 @@ static void timer_ping(void *arg) {
|
|||||||
(void) arg;
|
(void) arg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SNTP connection event handler. When we get a response from an SNTP server,
|
|
||||||
// adjust s_boot_timestamp. We'll get a valid time from that point on
|
|
||||||
static void sntp_ev_handler(struct mg_connection *c, int ev, void *ev_data) {
|
|
||||||
uint64_t *expiration_time = (uint64_t *) c->data;
|
|
||||||
if (ev == MG_EV_OPEN) {
|
|
||||||
*expiration_time = mg_millis() + 3000; // Store expiration time in 3s
|
|
||||||
} else if (ev == MG_EV_SNTP_TIME) {
|
|
||||||
uint64_t t = *(uint64_t *) ev_data;
|
|
||||||
s_boot_timestamp = t - mg_millis();
|
|
||||||
c->is_closing = 1;
|
|
||||||
} else if (ev == MG_EV_POLL) {
|
|
||||||
if (mg_millis() > *expiration_time) c->is_closing = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_sntp(void *param) { // SNTP timer function. Sync up time
|
static void timer_sntp(void *param) { // SNTP timer function. Sync up time
|
||||||
static uint64_t hourly_timer = 0;
|
static uint64_t hourly_timer = 0;
|
||||||
if (s_boot_timestamp == 0 ||
|
uint64_t t1 = mg_now(), t2 = mg_millis();
|
||||||
mg_timer_expired(&hourly_timer, 3600000, mg_millis())) {
|
if (t1 < t2 + 3600 || mg_timer_expired(&hourly_timer, 3600000, t2)) {
|
||||||
mg_sntp_connect(param, "udp://time.google.com:123", sntp_ev_handler, NULL);
|
mg_sntp_connect(param, "udp://time.google.com:123", NULL, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,11 +261,8 @@ void web_init(struct mg_mgr *mgr) {
|
|||||||
|
|
||||||
// Configure JSON-RPC functions we're going to handle
|
// Configure JSON-RPC functions we're going to handle
|
||||||
mg_rpc_add(&s_rpc, mg_str("config.set"), rpc_config_set, NULL);
|
mg_rpc_add(&s_rpc, mg_str("config.set"), rpc_config_set, NULL);
|
||||||
mg_rpc_add(&s_rpc, mg_str("ota.commit"), rpc_ota_commit, NULL);
|
|
||||||
mg_rpc_add(&s_rpc, mg_str("ota.rollback"), rpc_ota_rollback, NULL);
|
|
||||||
mg_rpc_add(&s_rpc, mg_str("ota.upload"), rpc_ota_upload, NULL);
|
mg_rpc_add(&s_rpc, mg_str("ota.upload"), rpc_ota_upload, NULL);
|
||||||
mg_rpc_add(&s_rpc, mg_str("device.reset"), rpc_device_reset, NULL);
|
|
||||||
|
|
||||||
mg_timer_add(mgr, 3000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_reconnect,
|
mg_timer_add(mgr, 3000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_reconnect,
|
||||||
mgr);
|
mgr);
|
||||||
mg_timer_add(mgr, ping_interval_ms, MG_TIMER_REPEAT, timer_ping, mgr);
|
mg_timer_add(mgr, ping_interval_ms, MG_TIMER_REPEAT, timer_ping, mgr);
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
BOARD = mcxn947
|
||||||
|
IDE = GCC+make
|
||||||
|
RTOS = baremetal
|
||||||
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
|
|
||||||
|
all build example: firmware.bin
|
||||||
|
|
||||||
|
firmware.bin: wizard
|
||||||
|
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
|
||||||
|
|
||||||
|
wizard:
|
||||||
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard ; rm mongoose.[ch] ; ln -s ../../../../mongoose.c ; ln -s ../../../../mongoose.h
|
||||||
|
|
||||||
|
|
||||||
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/??
|
||||||
|
update: firmware.bin
|
||||||
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
|
test update: CFLAGS_EXTRA ="-DUART_DEBUG=USART?"
|
||||||
|
test: update
|
||||||
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=15 | tee /tmp/output.txt
|
||||||
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf firmware.* wizard*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=mcxn947&ide=GCC+make&rtos=baremetal&file=README.md)
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
BOARD = mcxn947
|
||||||
|
IDE = GCC+make
|
||||||
|
RTOS = FreeRTOS
|
||||||
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
|
|
||||||
|
all build example: firmware.bin
|
||||||
|
|
||||||
|
firmware.bin: wizard
|
||||||
|
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
|
||||||
|
|
||||||
|
wizard:
|
||||||
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard ; rm mongoose.[ch] ; ln -s ../../../../mongoose.c ; ln -s ../../../../mongoose.h
|
||||||
|
|
||||||
|
|
||||||
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/??
|
||||||
|
update: firmware.bin
|
||||||
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
|
test update: CFLAGS_EXTRA ="-DUART_DEBUG=USART?"
|
||||||
|
test: update
|
||||||
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=15 | tee /tmp/output.txt
|
||||||
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf firmware.* wizard*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=mcxn947&ide=GCC+make&rtos=FreeRTOS&file=README.md)
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
BOARD = mcxn947
|
||||||
|
IDE = MCUXpresso
|
||||||
|
RTOS = baremetal
|
||||||
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
|
|
||||||
|
TARGET ?= Debug
|
||||||
|
DOCKER = docker run --rm -v $(CURDIR):/root -w /root
|
||||||
|
IMAGE ?= scaprile/xpresso
|
||||||
|
HEADLESS_BUILD = /usr/local/mcuxpressoide/ide/mcuxpressoide --launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild
|
||||||
|
|
||||||
|
all build example: firmware.axf
|
||||||
|
|
||||||
|
firmware.axf: wizard
|
||||||
|
mkdir -p workspace
|
||||||
|
PROJNAME=`xq -r .projectDescription.name wizard/.project` && \
|
||||||
|
($(DOCKER) $(IMAGE) $(HEADLESS_BUILD) -data workspace -import wizard -cleanBuild $$PROJNAME/$(TARGET) || true) && \
|
||||||
|
cp wizard/$(TARGET)/$$PROJNAME.axf firmware.axf
|
||||||
|
|
||||||
|
wizard:
|
||||||
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard/source ; rm mongoose.[ch] ; cp -rL ../../../../../mongoose.[ch] .
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
sudo rm -rf firmware.* wizard* workspace mcuxpresso .cache .eclipse .p2
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=f429&ide=CubeIDE&rtos=baremetal&file=README.md)
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
BOARD = mcxn947
|
||||||
|
IDE = MCUXpresso
|
||||||
|
RTOS = FreeRTOS
|
||||||
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
|
|
||||||
|
TARGET ?= Debug
|
||||||
|
DOCKER = docker run --rm -v $(CURDIR):/root -w /root
|
||||||
|
IMAGE ?= scaprile/xpresso
|
||||||
|
HEADLESS_BUILD = /usr/local/mcuxpressoide/ide/mcuxpressoide --launcher.suppressErrors -nosplash -application org.eclipse.cdt.managedbuilder.core.headlessbuild
|
||||||
|
|
||||||
|
all build example: firmware.axf
|
||||||
|
|
||||||
|
firmware.axf: wizard
|
||||||
|
mkdir -p workspace
|
||||||
|
PROJNAME=`xq -r .projectDescription.name wizard/.project` && \
|
||||||
|
($(DOCKER) $(IMAGE) $(HEADLESS_BUILD) -data workspace -import wizard -cleanBuild $$PROJNAME/$(TARGET) || true) && \
|
||||||
|
cp wizard/$(TARGET)/$$PROJNAME.axf firmware.axf
|
||||||
|
|
||||||
|
wizard:
|
||||||
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard/source ; rm mongoose.[ch] ; cp -rL ../../../../../mongoose.[ch] .
|
||||||
|
|
||||||
|
|
||||||
|
clean:
|
||||||
|
sudo rm -rf firmware.* wizard* workspace mcuxpresso .cache .eclipse .p2
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=f429&ide=CubeIDE&rtos=baremetal&file=README.md)
|
||||||
@@ -1,85 +1,29 @@
|
|||||||
CFLAGS = -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion
|
BOARD = rt1020
|
||||||
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
|
IDE = GCC+make
|
||||||
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
|
RTOS = baremetal
|
||||||
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1021
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
CFLAGS += -Icmsis_mcu/devices/MIMXRT1021/drivers -DCPU_MIMXRT1021DAG5A
|
|
||||||
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 $(CFLAGS_EXTRA)
|
|
||||||
LDSCRIPT = link.ld
|
|
||||||
LDFLAGS ?= -T$(LDSCRIPT) -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
|
||||||
|
|
||||||
SOURCES = main.c syscalls.c sysinit.c
|
|
||||||
SOURCES += cmsis_mcu/devices/MIMXRT1021/gcc/startup_MIMXRT1021.S # NXP startup file. Compiler-dependent!
|
|
||||||
CFLAGS += -D__ATOLLIC__ -D__STARTUP_CLEAR_BSS # Make startup code work as expected
|
|
||||||
|
|
||||||
# Mongoose options are defined in mongoose_config.h
|
|
||||||
SOURCES += mongoose.c net.c packed_fs.c
|
|
||||||
|
|
||||||
# Example specific build options. See README.md
|
|
||||||
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\"
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
|
||||||
RM = cmd /C del /Q /F /S
|
|
||||||
else
|
|
||||||
RM = rm -rf
|
|
||||||
endif
|
|
||||||
|
|
||||||
all build example update: SOURCES += flash_image.c
|
|
||||||
all build example: firmware.bin
|
all build example: firmware.bin
|
||||||
|
|
||||||
ram: LDSCRIPT = link_ram.ld
|
firmware.bin: wizard
|
||||||
ram: firmware.bin
|
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
|
||||||
|
|
||||||
firmware.bin: firmware.elf
|
wizard:
|
||||||
arm-none-eabi-objcopy -O binary $< $@
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard ; rm mongoose.[ch] ; ln -s ../../../../mongoose.c ; ln -s ../../../../mongoose.h
|
||||||
|
|
||||||
firmware.elf: cmsis_core cmsis_mcu $(SOURCES) hal.h link_ram.ld link.ld Makefile
|
|
||||||
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
|
||||||
arm-none-eabi-size $@
|
|
||||||
|
|
||||||
flash: firmware.bin
|
|
||||||
# flash
|
|
||||||
|
|
||||||
cmsis_core: # ARM CMSIS core headers
|
|
||||||
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
|
||||||
cmsis_mcu:
|
|
||||||
curl -sL https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1021_DFP.17.0.0.pack -o $@.zip
|
|
||||||
mkdir $@ && cd $@ && unzip -q ../$@.zip
|
|
||||||
mbedtls: # mbedTLS library
|
|
||||||
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
|
||||||
|
|
||||||
ifeq ($(TLS), mbedtls)
|
|
||||||
CFLAGS += -DMG_TLS=MG_TLS_MBED -Wno-conversion -Imbedtls/include
|
|
||||||
CFLAGS += -DMBEDTLS_CONFIG_FILE=\"mbedtls_config.h\" mbedtls/library/*.c
|
|
||||||
firmware.elf: mbedtls
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/4
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/4
|
||||||
update: firmware.bin
|
update: firmware.bin
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
update updateram: CFLAGS += -DUART_DEBUG=LPUART2
|
test update: CFLAGS_EXTRA ="-DUART_DEBUG=LPUART2"
|
||||||
|
|
||||||
test: update
|
test: update
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=15 | tee /tmp/output.txt
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
|
|
||||||
updateram: ram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @firmware.bin
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0003 wm,e000edfc,1 wm,e000ed0c,5fa0004"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
PC=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,4"}' | jq -r .resp[5:]` && \
|
|
||||||
SP=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,0"}' | jq -r .resp[5:]` && \
|
|
||||||
REQ="wm,e000ed08,0 wr,d,$$SP wr,f,$$PC" && \
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"'"$$REQ"'"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0001"}'
|
|
||||||
|
|
||||||
testram: updateram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) firmware.* *.su cmsis_core cmsis_mcu mbedtls *.zip
|
rm -rf firmware.* wizard*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=rt1020&ide=GCC+make&rtos=baremetal&file=README.md)
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2021 NXP
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __DCD_DATA \
|
|
||||||
0xD2, 0x03, 0xE0, 0x41, 0xCC, 0x03, 0x5C, 0x04, 0x40, 0x0F, 0xC0, 0x68, \
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, \
|
|
||||||
0x40, 0x0F, 0xC0, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x74, \
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, \
|
|
||||||
0x40, 0x0F, 0xC0, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x80, \
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0D, 0x80, 0x30, 0x00, 0x00, 0x20, 0x01, \
|
|
||||||
0x40, 0x0D, 0x81, 0x00, 0x10, 0x18, 0x10, 0x1B, 0x40, 0x0F, 0xC0, 0x14, \
|
|
||||||
0x00, 0x0A, 0x83, 0x40, 0x40, 0x1F, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x1C, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x24, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x28, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x34, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x40, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x48, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x4C, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x50, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x58, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x5C, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x64, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x68, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x70, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x74, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x7C, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x84, 0x00, 0x00, 0x00, 0x10, 0x40, 0x1F, 0x80, 0x88, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x8C, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x94, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x98, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xA0, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xA4, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xAC, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xB0, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x81, 0x88, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0x8C, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0x90, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0x94, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0x98, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0x9C, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xA0, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xA4, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xA8, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xAC, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xB0, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xB4, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xB8, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xBC, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xC0, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xC4, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xC8, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xCC, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xD0, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xD4, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xD8, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xDC, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xE0, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xE4, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xE8, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xEC, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xF0, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x81, 0xF4, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xF8, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x81, 0xFC, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x82, 0x00, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x82, 0x04, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x82, 0x08, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x82, 0x0C, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x82, 0x10, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x82, 0x14, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x82, 0x18, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x82, 0x1C, \
|
|
||||||
0x00, 0x00, 0x00, 0xE1, 0x40, 0x1F, 0x82, 0x20, 0x00, 0x00, 0x00, 0xE1, \
|
|
||||||
0x40, 0x1F, 0x82, 0x24, 0x00, 0x00, 0x00, 0xE1, 0x40, 0x2F, 0x00, 0x00, \
|
|
||||||
0x10, 0x00, 0x00, 0x04, 0x40, 0x2F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x81, \
|
|
||||||
0x40, 0x2F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x81, 0x40, 0x2F, 0x00, 0x10, \
|
|
||||||
0x80, 0x00, 0x00, 0x1B, 0x40, 0x2F, 0x00, 0x14, 0x82, 0x00, 0x00, 0x1B, \
|
|
||||||
0x40, 0x2F, 0x00, 0x18, 0x84, 0x00, 0x00, 0x1B, 0x40, 0x2F, 0x00, 0x04, \
|
|
||||||
0x00, 0x00, 0x79, 0x88, 0x40, 0x2F, 0x00, 0x40, 0x00, 0x00, 0x0F, 0x07, \
|
|
||||||
0x40, 0x2F, 0x00, 0x44, 0x00, 0x65, 0x29, 0x22, 0x40, 0x2F, 0x00, 0x48, \
|
|
||||||
0x00, 0x01, 0x09, 0x20, 0x40, 0x2F, 0x00, 0x4C, 0x50, 0x21, 0x0A, 0x08, \
|
|
||||||
0x40, 0x2F, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, 0x40, 0x2F, 0x00, 0x84, \
|
|
||||||
0x00, 0x88, 0x88, 0x88, 0x40, 0x2F, 0x00, 0x94, 0x00, 0x00, 0x00, 0x02, \
|
|
||||||
0x40, 0x2F, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2F, 0x00, 0x90, \
|
|
||||||
0x80, 0x00, 0x00, 0x00, 0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0F, \
|
|
||||||
0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, \
|
|
||||||
0xCC, 0x00, 0x14, 0x04, 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0C, 0xCF, 0x00, 0x0C, 0x1C, \
|
|
||||||
0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0xCC, 0x00, 0x14, 0x04, \
|
|
||||||
0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, 0x40, 0x2F, 0x00, 0x9C, \
|
|
||||||
0xA5, 0x5A, 0x00, 0x0C, 0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, \
|
|
||||||
0x00, 0x00, 0x00, 0x01, 0xCC, 0x00, 0x1C, 0x04, 0x40, 0x2F, 0x00, 0xA0, \
|
|
||||||
0x00, 0x00, 0x00, 0x30, 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0A, 0xCF, 0x00, 0x0C, 0x1C, \
|
|
||||||
0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0xCC, 0x00, 0x0C, 0x04, \
|
|
||||||
0x40, 0x2F, 0x00, 0x4C, 0x50, 0x21, 0x0A, 0x09
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#include "dcd.h" // pin settings for MIMXRT1020-EVK board
|
|
||||||
#include "fsl_flexspi.h" // peripheral structures
|
|
||||||
#include "fsl_romapi.h" // peripheral structures
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
extern uint32_t __isr_vector[];
|
|
||||||
|
|
||||||
// RM 9.7.2
|
|
||||||
__attribute__((section(".dcd"), used))
|
|
||||||
const uint8_t __ivt_dcd_data[] = {__DCD_DATA};
|
|
||||||
|
|
||||||
// RM 9.7.1
|
|
||||||
__attribute__((section(".dat"), used)) const uint32_t __ivt_boot_data[] = {
|
|
||||||
FlexSPI_AMBA_BASE, // boot start location
|
|
||||||
8 * 1024 * 1024, // size
|
|
||||||
0, // Plugin flag
|
|
||||||
0Xffffffff // empty - extra data word
|
|
||||||
};
|
|
||||||
|
|
||||||
__attribute__((section(".ivt"), used)) const uint32_t __ivt[8] = {
|
|
||||||
0x412000d1, // header: 41 - version, 2000 size, d1 tag
|
|
||||||
(uint32_t) __isr_vector, // entry
|
|
||||||
0, // reserved
|
|
||||||
(uint32_t) __ivt_dcd_data, // dcd
|
|
||||||
(uint32_t) __ivt_boot_data, // boot data
|
|
||||||
(uint32_t) __ivt, // this is us - ivt absolute address
|
|
||||||
0, // csf absolute address
|
|
||||||
0, // reserved for HAB
|
|
||||||
};
|
|
||||||
|
|
||||||
#define __FLEXSPI_QSPI_LUT { \
|
|
||||||
[0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), \
|
|
||||||
[1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),\
|
|
||||||
[4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),\
|
|
||||||
[4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0),\
|
|
||||||
[4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x18),\
|
|
||||||
[4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18),\
|
|
||||||
[4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),\
|
|
||||||
[4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),\
|
|
||||||
[4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0),\
|
|
||||||
}
|
|
||||||
|
|
||||||
// MIMXRT1060-EVKB flash chip config: S25LP064A-JBLE
|
|
||||||
__attribute__((section(".cfg"), used))
|
|
||||||
const flexspi_nor_config_t __qspi_flash_cfg = {
|
|
||||||
.memConfig = {.tag = FLEXSPI_CFG_BLK_TAG,
|
|
||||||
.version = FLEXSPI_CFG_BLK_VERSION,
|
|
||||||
.readSampleClkSrc = 1, // ReadSampleClk_LoopbackFromDqsPad
|
|
||||||
.csHoldTime = 3,
|
|
||||||
.csSetupTime = 3,
|
|
||||||
.controllerMiscOption = BIT(4),
|
|
||||||
.deviceType = 1, // serial NOR
|
|
||||||
.sflashPadType = 4,
|
|
||||||
.serialClkFreq = 7, // 133MHz
|
|
||||||
.sflashA1Size = 8 * 1024 * 1024,
|
|
||||||
.lookupTable = __FLEXSPI_QSPI_LUT},
|
|
||||||
.pageSize = 256,
|
|
||||||
.sectorSize = 4 * 1024,
|
|
||||||
.ipcmdSerialClkFreq = 1,
|
|
||||||
.blockSize = 64 * 1024,
|
|
||||||
.isUniformBlockSize = false};
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
// https://www.nxp.com/webapp/Download?colCode=IMXRT1020RM
|
|
||||||
// https://cache.nxp.com/secured/assets/documents/en/user-guide/MIMXRT1020EVKHUG.pdf
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "MIMXRT1021.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BIT(x) (1UL << (x))
|
|
||||||
#define SETBITS(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK)
|
|
||||||
#define PIN(bank, num) ((((bank) - '0') << 8) | (num))
|
|
||||||
#define PINNO(pin) (pin & 255)
|
|
||||||
#define PINBANK(pin) (pin >> 8)
|
|
||||||
|
|
||||||
// Use LED for blinking, GPIO_AD_B0_05. GPIO1.5 (schematics)
|
|
||||||
#define LED PIN('1', 5)
|
|
||||||
|
|
||||||
#ifndef UART_DEBUG
|
|
||||||
#define UART_DEBUG LPUART1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// No settable constants, see sysinit.c
|
|
||||||
#define SYS_FREQUENCY 500000000UL
|
|
||||||
|
|
||||||
static inline void spin(volatile uint32_t count) {
|
|
||||||
while (count--) (void) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { CLOCK_OFF = 0U, CLOCK_ON_RUN = 1U, CLOCK_ON_RUN_WAIT = 3U };
|
|
||||||
static inline void clock_periph(uint32_t index, uint32_t shift, uint32_t val) {
|
|
||||||
volatile uint32_t *r = &CCM->CCGR0;
|
|
||||||
SETBITS(r[index], 3UL << shift, val << shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
// which peripheral feeds the pin
|
|
||||||
static inline void gpio_mux_config(uint16_t index, uint8_t af) {
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[index] = af;
|
|
||||||
}
|
|
||||||
|
|
||||||
// which pin feeds the peripheral (2nd stage)
|
|
||||||
static inline void periph_mux_config(uint16_t index, uint8_t in) {
|
|
||||||
IOMUXC->SELECT_INPUT[index] = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT };
|
|
||||||
enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN };
|
|
||||||
enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_MEDIUM_, GPIO_SPEED_HIGH };
|
|
||||||
enum { GPIO_PULL_NONE, GPIO_PULL_DOWN, GPIO_PULL_UP };
|
|
||||||
static inline GPIO_Type *gpio_bank(uint16_t pin) {
|
|
||||||
static const GPIO_Type *g[] = {NULL, GPIO1, GPIO2, GPIO3, NULL, GPIO5};
|
|
||||||
return (GPIO_Type *) g[PINBANK(pin)];
|
|
||||||
}
|
|
||||||
|
|
||||||
// pin driver/pull-up/down configuration (ignore "keeper")
|
|
||||||
static inline void gpio_pad_config(uint16_t index, uint8_t type, uint8_t speed,
|
|
||||||
uint8_t pull) {
|
|
||||||
bool dopull = pull > 0;
|
|
||||||
if (dopull) --pull;
|
|
||||||
IOMUXC->SW_PAD_CTL_PAD[index] =
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_ODE(type) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SRE(speed >= GPIO_SPEED_HIGH) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUE(1) | IOMUXC_SW_PAD_CTL_PAD_PKE(dopull) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUS(pull) | IOMUXC_SW_PAD_CTL_PAD_DSE(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
|
|
||||||
uint8_t speed, uint8_t pull) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint8_t bit = (uint8_t) PINNO(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
switch (PINBANK(pin)) {
|
|
||||||
case 1:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(1, CCM_CCGR1_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(0, CCM_CCGR0_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_mux_config(bit < 13
|
|
||||||
? kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32 + bit
|
|
||||||
: kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 + bit - 13,
|
|
||||||
5);
|
|
||||||
gpio_pad_config(bit < 13
|
|
||||||
? kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_32 + bit
|
|
||||||
: kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_00 + bit - 13,
|
|
||||||
type, speed, pull);
|
|
||||||
clock_periph(2, CCM_CCGR2_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// TODO(): support sw_mux
|
|
||||||
clock_periph(1, CCM_CCGR1_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio->IMR &= ~mask;
|
|
||||||
if (mode == GPIO_MODE_INPUT) {
|
|
||||||
gpio->GDIR &= ~mask;
|
|
||||||
} else {
|
|
||||||
gpio->GDIR |= mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_input(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
static inline void gpio_output(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool gpio_read(uint16_t pin) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
return gpio->DR & mask;
|
|
||||||
}
|
|
||||||
static inline void gpio_write(uint16_t pin, bool value) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
if (value) {
|
|
||||||
gpio->DR |= mask;
|
|
||||||
} else {
|
|
||||||
gpio->DR &= ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_toggle(uint16_t pin) {
|
|
||||||
gpio_write(pin, !gpio_read(pin));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 14.5 Table 14-4: uart_clk_root
|
|
||||||
// see sysinit.c for clocks, (14.7.9: defaults to PLL3/6/1 = 80MHz)
|
|
||||||
static inline void uart_init(LPUART_Type *uart, unsigned long baud) {
|
|
||||||
uint8_t af = 2; // Alternate function
|
|
||||||
uint16_t mr = 0, pr = 0, mt = 0, pt = 0; // pins
|
|
||||||
uint32_t freq = 80000000; // uart_clk_root frequency
|
|
||||||
if (uart == LPUART1)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_06,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_06,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_07,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_07;
|
|
||||||
if (uart == LPUART2)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_08,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_09,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09;
|
|
||||||
|
|
||||||
if (uart == LPUART1) clock_periph(5, CCM_CCGR5_CG12_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
if (uart == LPUART2) clock_periph(0, CCM_CCGR0_CG14_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(mt, af);
|
|
||||||
gpio_pad_config(pt, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(mr, af);
|
|
||||||
gpio_pad_config(pr, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
uart->GLOBAL |= LPUART_GLOBAL_RST_MASK; // reset, CTRL = 0, defaults
|
|
||||||
uart->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
|
|
||||||
SETBITS(uart->BAUD,
|
|
||||||
LPUART_BAUD_OSR_MASK | LPUART_BAUD_SBR_MASK | LPUART_BAUD_SBNS_MASK,
|
|
||||||
LPUART_BAUD_OSR(16 - 1) |
|
|
||||||
LPUART_BAUD_SBR(freq / (16 * baud))); // Rx sample at 16x
|
|
||||||
SETBITS(uart->CTRL,
|
|
||||||
LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK |
|
|
||||||
LPUART_CTRL_IDLECFG_MASK,
|
|
||||||
LPUART_CTRL_IDLECFG(1) | LPUART_CTRL_ILT(1) |
|
|
||||||
LPUART_BAUD_SBNS(0)); // no parity, idle 2 chars after 1 stop bit
|
|
||||||
uart->CTRL |= LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void uart_write_byte(LPUART_Type *uart, uint8_t byte) {
|
|
||||||
uart->DATA = byte;
|
|
||||||
while ((uart->STAT & LPUART_STAT_TDRE_MASK) == 0) spin(1);
|
|
||||||
}
|
|
||||||
static inline void uart_write_buf(LPUART_Type *uart, char *buf, size_t len) {
|
|
||||||
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
|
|
||||||
}
|
|
||||||
static inline int uart_read_ready(LPUART_Type *uart) {
|
|
||||||
(void) uart;
|
|
||||||
return uart->STAT & LPUART_STAT_RDRF_MASK;
|
|
||||||
}
|
|
||||||
static inline uint8_t uart_read_byte(LPUART_Type *uart) {
|
|
||||||
return (uint8_t) (uart->DATA & 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rng_init(void) {
|
|
||||||
clock_periph(6, CCM_CCGR6_CG6_SHIFT, CLOCK_ON_RUN_WAIT); // trng_clk
|
|
||||||
SETBITS(TRNG->MCTL,
|
|
||||||
TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK | TRNG_MCTL_RST_DEF_MASK,
|
|
||||||
TRNG_MCTL_PRGM(1) | TRNG_MCTL_ERR(1) |
|
|
||||||
TRNG_MCTL_RST_DEF(1)); // reset to default values
|
|
||||||
SETBITS(TRNG->MCTL, TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK,
|
|
||||||
TRNG_MCTL_PRGM(0)); // set to run mode
|
|
||||||
(void) TRNG->ENT[TRNG_ENT_COUNT - 1]; // start new entropy generation
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
}
|
|
||||||
static inline uint32_t rng_read(void) {
|
|
||||||
static uint8_t idx = 0;
|
|
||||||
while ((TRNG->MCTL & TRNG_MCTL_ENT_VAL_MASK) == 0) (void) 0;
|
|
||||||
uint32_t data = TRNG->ENT[idx++]; // read data
|
|
||||||
idx %= TRNG_ENT_COUNT; // stay within array limits
|
|
||||||
if (idx == 0) // we've just read TRNG_ENT_COUNT - 1
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - PHY has no xtal, XI driven from ENET_REF_CLK1 (labeled as ENET_TX_CLK
|
|
||||||
// (GPIO_AD_B0_08)), generated by the MCU
|
|
||||||
// - PHY RST connected to GPIO1.4 (GPIO_AD_B0_04); INTRP/NAND_TREE connected to
|
|
||||||
// GPIO1.22 (GPIO_AD_B1_06)
|
|
||||||
// - 37.4 REF_CLK1 is RMII mode reference clock for Rx, Tx, and SMI; it is I/O
|
|
||||||
// - 11.4.2 IOMUXC_GPR_GPR1 bit 17: ENET_REF_CLK_DIR --> 1 ENET_REF_CLK is
|
|
||||||
// output driven by ref_enetpll0
|
|
||||||
// - 14.6.1.3.4 Ethernet PLL (PLL6)
|
|
||||||
static inline void ethernet_init(void) {
|
|
||||||
gpio_init(PIN('1', 4), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP); // set GPIO1.4 as GPIO (PHY \RST)
|
|
||||||
gpio_write(PIN('1', 4), 0); // reset PHY
|
|
||||||
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_08,
|
|
||||||
4); // set for ENET_REF_CLK1
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_08] |=
|
|
||||||
IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RMII_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_08, so RMII clock is taken
|
|
||||||
// from ENET_REF_CLK1
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_08, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_09, 0); // set for RXDATA1
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_DATA1_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_09
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_09, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_10, 0); // set for RXDATA0
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_DATA0_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_10
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_10, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_11, 0); // set for CRS
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_EN_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_11
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_11, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12, 0); // set for RXERR
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_ERR_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_12
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_12, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13, 0); // set for TXEN
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_13, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_14, 0); // set for TXDATA0
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_14, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_15, 0); // set for TXDATA1
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_15, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_40, 4); // set for MDIO
|
|
||||||
periph_mux_config(kIOMUXC_ENET_MDIO_SELECT_INPUT,
|
|
||||||
2); // drive peripheral from EMC_40
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_40, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_41, 4); // set for MDC
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_41, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
gpio_init(PIN('1', 22), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // set GPIO1.22 as GPIO (PHY INTRP/NAND_TREE)
|
|
||||||
gpio_write(PIN('1', 22), 1); // prevent NAND_TREE
|
|
||||||
// 14.8.9 Use 500MHz reference and generate 50MHz. This is done at sysinit.c,
|
|
||||||
// as we use this source to clock the core
|
|
||||||
spin(10000); // keep PHY RST low for a while
|
|
||||||
gpio_write(PIN('1', 4), 1); // deassert RST
|
|
||||||
gpio_init(PIN('1', 22), GPIO_MODE_INPUT, 0, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // setup IRQ (pulled-up)(not used)
|
|
||||||
|
|
||||||
IOMUXC_GPR->GPR1 |=
|
|
||||||
IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR(1); // Set ENET_REF_CLK1 as output
|
|
||||||
clock_periph(1, CCM_CCGR1_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enet_ipg_clk
|
|
||||||
NVIC_EnableIRQ(ENET_IRQn); // Setup Ethernet IRQ handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper macro for MAC generation, byte reads not allowed
|
|
||||||
#define GENERATE_LOCALLY_ADMINISTERED_MAC() \
|
|
||||||
{ \
|
|
||||||
2, OCOTP->CFG0 & 255, (OCOTP->CFG0 >> 10) & 255, \
|
|
||||||
((OCOTP->CFG0 >> 19) ^ (OCOTP->CFG1 >> 19)) & 255, \
|
|
||||||
(OCOTP->CFG1 >> 10) & 255, OCOTP->CFG1 & 255 \
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void flash_init(void) { // QSPI in FlexSPI
|
|
||||||
// set pins
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05, 1); // set for DQS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_05, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11, 1); // set for SS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_11, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07, 1); // set for SCLK
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_SCLK_SELECT_INPUT, 0); // drive peripheral from B1_07
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_07, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08, 1); // set for DATA0
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA0_SELECT_INPUT, 0); // drive peripheral from B1_08
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_08, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10, 1); // set for DATA1
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA1_SELECT_INPUT, 0); // drive peripheral from B1_10
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_10, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09, 1); // set for DATA2
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA2_SELECT_INPUT, 0); // drive peripheral from B1_09
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_09, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06, 1); // set for DATA3
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA3_SELECT_INPUT, 0); // drive peripheral from B1_06
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_06, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
// set FlexSPI clock
|
|
||||||
SETBITS(CCM->CSCMR1, CCM_CSCMR1_FLEXSPI_CLK_SEL_MASK | CCM_CSCMR1_FLEXSPI_PODF_MASK, CCM_CSCMR1_FLEXSPI_CLK_SEL(3) | CCM_CSCMR1_FLEXSPI_PODF(3)); // select PLL3 PFD0 /4
|
|
||||||
clock_periph(6, CCM_CCGR6_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enable
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
ENTRY(Reset_Handler);
|
|
||||||
MEMORY {
|
|
||||||
flash_hdr(rx) : ORIGIN = 0x60000000, LENGTH = 8k
|
|
||||||
flash_irq(rx) : ORIGIN = 0x60002000, LENGTH = 1k
|
|
||||||
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8183k
|
|
||||||
|
|
||||||
itcram(rx) : ORIGIN = 0x00000000, LENGTH = 64k
|
|
||||||
dtcram(rw) : ORIGIN = 0x20000000, LENGTH = 64k
|
|
||||||
ocram(rw) : ORIGIN = 0x20200000, LENGTH = 128k
|
|
||||||
}
|
|
||||||
__StackTop = ORIGIN(dtcram) + LENGTH(dtcram);
|
|
||||||
|
|
||||||
/* TODO(): separate itcram and go back to using dtcram for data and bss when ota is finished */
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
.hdr : { FILL(0xff) ; KEEP(*(.cfg)) . = 0x1000 ; KEEP(*(.ivt)) . = 0x1020 ;
|
|
||||||
KEEP(*(.dat)) . = 0x1030 ; KEEP(*(.dcd)) . = 0x2000 ;} >flash_hdr
|
|
||||||
.irq : { KEEP(*(.isr_vector)) } > flash_irq
|
|
||||||
.text : { *(.text* .text.*) *(.rodata*) ; } > flash_code
|
|
||||||
.data : { __data_start__ = .; *(.data SORT(.data.*)) *(.iram) __data_end__ = .; } > itcram AT > flash_code
|
|
||||||
__etext = LOADADDR(.data);
|
|
||||||
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > itcram
|
|
||||||
_end = .;
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
// Copyright (c) 2022-2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "mongoose.h"
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
|
|
||||||
|
|
||||||
static volatile uint64_t s_ticks; // Milliseconds since boot
|
|
||||||
void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
|
|
||||||
s_ticks++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
|
||||||
return s_ticks; // Return number of milliseconds since boot
|
|
||||||
}
|
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
|
||||||
uint32_t r = rng_read();
|
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
gpio_toggle(LED); // Blink LED
|
|
||||||
struct mg_tcpip_if *ifp = arg; // And show
|
|
||||||
const char *names[] = {"down", "up", "req", "ready"}; // network stats
|
|
||||||
MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
|
||||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
|
||||||
ifp->ndrop, ifp->nerr));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
gpio_output(LED); // Setup blue LED
|
|
||||||
uart_init(UART_DEBUG, 115200); // Initialise debug printf
|
|
||||||
ethernet_init(); // Initialise ethernet pins
|
|
||||||
MG_INFO(("Starting, CPU freq %g MHz", (double) SystemCoreClock / 1000000));
|
|
||||||
|
|
||||||
struct mg_mgr mgr; // Initialise
|
|
||||||
mg_mgr_init(&mgr); // Mongoose event manager
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
|
|
||||||
// Initialise Mongoose network stack
|
|
||||||
struct mg_tcpip_driver_imxrt_data driver_data = {.mdc_cr = 24, .phy_addr = 2};
|
|
||||||
struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC(),
|
|
||||||
// Uncomment below for static configuration:
|
|
||||||
// .ip = mg_htonl(MG_U32(192, 168, 0, 223)),
|
|
||||||
// .mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
|
||||||
// .gw = mg_htonl(MG_U32(192, 168, 0, 1)),
|
|
||||||
.driver = &mg_tcpip_driver_imxrt,
|
|
||||||
.driver_data = &driver_data};
|
|
||||||
mg_tcpip_init(&mgr, &mif);
|
|
||||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif);
|
|
||||||
|
|
||||||
MG_INFO(("MAC: %M. Waiting for IP...", mg_print_mac, mif.mac));
|
|
||||||
while (mif.state != MG_TCPIP_STATE_READY) {
|
|
||||||
mg_mgr_poll(&mgr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MG_INFO(("Initialising application..."));
|
|
||||||
web_init(&mgr);
|
|
||||||
|
|
||||||
MG_INFO(("Starting event loop"));
|
|
||||||
for (;;) {
|
|
||||||
mg_mgr_poll(&mgr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// See https://mongoose.ws/documentation/#build-options
|
|
||||||
#define MG_ARCH MG_ARCH_NEWLIB
|
|
||||||
#define MG_OTA MG_OTA_FLASH
|
|
||||||
#define MG_DEVICE MG_DEVICE_RT1020
|
|
||||||
|
|
||||||
#define MG_ENABLE_TCPIP 1
|
|
||||||
#define MG_ENABLE_DRIVER_IMXRT 1
|
|
||||||
#define MG_IO_SIZE 256
|
|
||||||
#define MG_ENABLE_CUSTOM_MILLIS 1
|
|
||||||
#define MG_ENABLE_CUSTOM_RANDOM 1
|
|
||||||
#define MG_ENABLE_PACKED_FS 1
|
|
||||||
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
int _fstat(int fd, struct stat *st) {
|
|
||||||
if (fd < 0) return -1;
|
|
||||||
st->st_mode = S_IFCHR;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *_sbrk(int incr) {
|
|
||||||
extern char _end;
|
|
||||||
static unsigned char *heap = NULL;
|
|
||||||
unsigned char *prev_heap;
|
|
||||||
unsigned char x = 0, *heap_end = (unsigned char *)((size_t) &x - 512);
|
|
||||||
(void) x;
|
|
||||||
if (heap == NULL) heap = (unsigned char *) &_end;
|
|
||||||
prev_heap = heap;
|
|
||||||
if (heap + incr > heap_end) return (void *) -1;
|
|
||||||
heap += incr;
|
|
||||||
return prev_heap;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _open(const char *path) {
|
|
||||||
(void) path;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _close(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isatty(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _lseek(int fd, int ptr, int dir) {
|
|
||||||
(void) fd, (void) ptr, (void) dir;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _exit(int status) {
|
|
||||||
(void) status;
|
|
||||||
for (;;) asm volatile("BKPT #0");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _kill(int pid, int sig) {
|
|
||||||
(void) pid, (void) sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getpid(void) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _write(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _read(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _link(const char *a, const char *b) {
|
|
||||||
(void) a, (void) b;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _unlink(const char *a) {
|
|
||||||
(void) a;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _stat(const char *path, struct stat *st) {
|
|
||||||
(void) path, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode) {
|
|
||||||
(void) path, (void) mode;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(void) {}
|
|
||||||
|
|
||||||
extern uint64_t mg_now(void);
|
|
||||||
|
|
||||||
int _gettimeofday(struct timeval *tv, void *tz) {
|
|
||||||
uint64_t now = mg_now();
|
|
||||||
(void) tz;
|
|
||||||
tv->tv_sec = (time_t) (now / 1000);
|
|
||||||
tv->tv_usec = (unsigned long) ((now % 1000) * 1000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// This file contains essentials required by the CMSIS:
|
|
||||||
// uint32_t SystemCoreClock - holds the system core clock value
|
|
||||||
// SystemInit() - initialises the system, e.g. sets up clocks
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
uint32_t SystemCoreClock = SYS_FREQUENCY;
|
|
||||||
|
|
||||||
// - 14.4, Figure 14-2: clock tree
|
|
||||||
// - 14.7.4: ARM_PODF defaults to /1
|
|
||||||
// - 14.7.5: AHB_PODF defaults to /1; PERIPH_CLK_SEL defaults to derive clock
|
|
||||||
// from pre_periph_clk_sel
|
|
||||||
// - 14.7.6: PRE_PERIPH_CLK_SEL defaults to derive clock from PLL2 PFD3.
|
|
||||||
// - (For 528MHz operation, we need to set it to derive clock from PLL2, but
|
|
||||||
// this chip max is 500 MHz).
|
|
||||||
// - 14.6.1.3.1 System PLL (PLL2); 13.3.2.2 PLLs; 14.6.1.4 Phase Fractional
|
|
||||||
// Dividers (PFD)
|
|
||||||
// - 14.8.2: PLL2 is powered off and bypassed to 24MHz
|
|
||||||
// - 14.8.11: PFD defaults to 18/16 but Figure 14-2 shows half the value
|
|
||||||
// ("divider")
|
|
||||||
// - For 500MHz operation, we need to set PRE_PERIPH_CLK_SEL to derive clock
|
|
||||||
// from divided PLL6
|
|
||||||
// - 14.8.9: configure PLL6 to generate a 500MHz clock
|
|
||||||
// - Datasheet 4.1.3: System frequency/Bus frequency max 500/125MHz respectively
|
|
||||||
// (AHB/IPG)
|
|
||||||
// - MCUXpresso: IPG_CLK_ROOT <= 125MHz; PERCLK_CLK_ROOT <= 62.5MHz
|
|
||||||
// - Datasheet 4.8.4.1.1/2: the processor clock frequency must exceed twice the
|
|
||||||
// ENET_RX_CLK/ENET_TX_CLK frequency.
|
|
||||||
// - Datasheet 4.8.4.2: no details for RMII (above is for MII), assumed 50MHz
|
|
||||||
// min processor clock
|
|
||||||
// - Datasheet 4.1.3, Table 11: "Overdrive" run mode requires 1.25V core voltage
|
|
||||||
// minimum
|
|
||||||
void SystemInit(void) { // Called automatically by startup code (ints masked)
|
|
||||||
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU
|
|
||||||
asm("DSB");
|
|
||||||
asm("ISB");
|
|
||||||
// 53.4.2: Disable watchdog after reset (unlocked)
|
|
||||||
RTWDOG->CS &= ~RTWDOG_CS_EN_MASK;
|
|
||||||
RTWDOG->TOVAL = 0xFFFF;
|
|
||||||
while (RTWDOG->CS & RTWDOG_CS_ULK_MASK) spin(1); // wait for lock
|
|
||||||
while ((RTWDOG->CS & RTWDOG_CS_RCS_MASK) == 0)
|
|
||||||
spin(1); // wait for new config
|
|
||||||
// Set VDD_SOC to 1.25V
|
|
||||||
SETBITS(DCDC->REG3, DCDC_REG3_TRG_MASK, DCDC_REG3_TRG(0x12));
|
|
||||||
while ((DCDC->REG0 & DCDC_REG0_STS_DC_OK_MASK) == 0)
|
|
||||||
spin(1); // Wait for DCDC_STS_DC_OK
|
|
||||||
// 14.8.9 Init 500MHz reference, clock the M7 core with it, generate 50MHz for
|
|
||||||
// ENET and RMII.
|
|
||||||
SETBITS(CCM_ANALOG->PLL_ENET, CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_MASK |
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(0)); // bypass to 24MHz osc
|
|
||||||
SETBITS(
|
|
||||||
CCM_ANALOG->PLL_ENET,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT(1) | CCM_ANALOG_PLL_ENET_ENABLE_MASK |
|
|
||||||
CCM_ANALOG_PLL_ENET_ENET_500M_REF_EN_MASK); // setup PLL
|
|
||||||
while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_ENET &=
|
|
||||||
~CCM_ANALOG_PLL_ENET_BYPASS_MASK; // Disable Bypass (switch to PLL)
|
|
||||||
SETBITS(CCM->CBCDR, CCM_CBCDR_IPG_PODF_MASK,
|
|
||||||
CCM_CBCDR_IPG_PODF(3)); // Set IPG divider /4 (125MHz)
|
|
||||||
SETBITS(CCM->CSCMR1, CCM_CSCMR1_PERCLK_PODF_MASK,
|
|
||||||
CCM_CSCMR1_PERCLK_PODF(1)); // Set PERCLK divider /2 (62.5MHz)
|
|
||||||
SETBITS(CCM->CBCMR, CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK,
|
|
||||||
CCM_CBCMR_PRE_PERIPH_CLK_SEL(3)); // run from 500MHz clock
|
|
||||||
// 14.5 Table 14-4: uart_clk_root
|
|
||||||
// 14.4: uart_clk_root = PLL3/6 or OSC; CCM_CSCDR1 (14.7.9) defaults to
|
|
||||||
// PLL3/6/1; but ROM boot code fiddles with the divider (9.5.3 Table 9-7)
|
|
||||||
CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_POWER_MASK; // Power PLL on
|
|
||||||
while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_USB1 &=
|
|
||||||
~CCM_ANALOG_PLL_USB1_BYPASS_MASK; // Disable Bypass (switch to PLL)
|
|
||||||
CCM->CSCDR1 &= ~(CCM_CSCDR1_UART_CLK_SEL_MASK | CCM_CSCDR1_UART_CLK_PODF_MASK);
|
|
||||||
rng_init(); // Initialise random number generator
|
|
||||||
// NXP startup code calls SystemInit BEFORE initializing RAM...
|
|
||||||
SysTick_Config(SYS_FREQUENCY / 1000); // Sys tick every 1ms
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
|
||||||
#define configCPU_CLOCK_HZ SYS_FREQUENCY
|
|
||||||
#define configTICK_RATE_HZ 1000
|
|
||||||
#define configMAX_PRIORITIES 5
|
|
||||||
#define configUSE_16_BIT_TICKS 0
|
|
||||||
#define configUSE_TICK_HOOK 0
|
|
||||||
#define configUSE_IDLE_HOOK 0
|
|
||||||
#define configUSE_TIMERS 0
|
|
||||||
#define configUSE_CO_ROUTINES 0
|
|
||||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
|
||||||
#define configMINIMAL_STACK_SIZE 128
|
|
||||||
#define configTOTAL_HEAP_SIZE (1024 * 32)
|
|
||||||
#define INCLUDE_vTaskDelay 1
|
|
||||||
#define INCLUDE_xTaskGetSchedulerState 1 // trying
|
|
||||||
|
|
||||||
#ifdef __NVIC_PRIO_BITS
|
|
||||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
|
||||||
#else
|
|
||||||
#define configPRIO_BITS 4
|
|
||||||
#endif
|
|
||||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
|
|
||||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY \
|
|
||||||
(configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
|
|
||||||
|
|
||||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
|
|
||||||
(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
|
|
||||||
|
|
||||||
#define configASSERT(expr) \
|
|
||||||
if (!(expr)) printf("FAILURE %s:%d: %s\n", __FILE__, __LINE__, #expr)
|
|
||||||
|
|
||||||
#define vPortSVCHandler SVC_Handler
|
|
||||||
#define xPortPendSVHandler PendSV_Handler
|
|
||||||
#define xPortSysTickHandler SysTick_Handler
|
|
||||||
@@ -1,84 +1,29 @@
|
|||||||
CFLAGS = -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion
|
BOARD = rt1020
|
||||||
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
|
IDE = GCC+make
|
||||||
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
|
RTOS = FreeRTOS
|
||||||
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1021
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
CFLAGS += -Icmsis_mcu/devices/MIMXRT1021/drivers -DCPU_MIMXRT1021DAG5A
|
|
||||||
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 $(CFLAGS_EXTRA)
|
|
||||||
LDSCRIPT = link.ld
|
|
||||||
LDFLAGS ?= -T$(LDSCRIPT) -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
|
||||||
|
|
||||||
SOURCES = main.c syscalls.c sysinit.c
|
|
||||||
SOURCES += cmsis_mcu/devices/MIMXRT1021/gcc/startup_MIMXRT1021.S # NXP startup file. Compiler-dependent!
|
|
||||||
CFLAGS += -D__ATOLLIC__ -D__STARTUP_CLEAR_BSS # Make startup code work as expected
|
|
||||||
|
|
||||||
# FreeRTOS. RT1020 has a Cortex-M7 r1p2 core, FreeRTOS recommends using CM4F port for non-r0p1 CM7 micros
|
|
||||||
SOURCES += FreeRTOS-Kernel/portable/MemMang/heap_4.c
|
|
||||||
SOURCES += FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c
|
|
||||||
CFLAGS += -IFreeRTOS-Kernel/include
|
|
||||||
CFLAGS += -IFreeRTOS-Kernel/portable/GCC/ARM_CM4F -Wno-conversion
|
|
||||||
|
|
||||||
# Mongoose options are defined in mongoose_config.h
|
|
||||||
SOURCES += mongoose.c net.c packed_fs.c
|
|
||||||
|
|
||||||
# Example specific build options. See README.md
|
|
||||||
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\"
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
|
||||||
RM = cmd /C del /Q /F /S
|
|
||||||
else
|
|
||||||
RM = rm -rf
|
|
||||||
endif
|
|
||||||
|
|
||||||
all build example update: SOURCES += flash_image.c
|
|
||||||
all build example: firmware.bin
|
all build example: firmware.bin
|
||||||
|
|
||||||
ram: LDSCRIPT = link_ram.ld
|
firmware.bin: wizard
|
||||||
ram: firmware.bin
|
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
|
||||||
|
|
||||||
firmware.bin: firmware.elf
|
wizard:
|
||||||
arm-none-eabi-objcopy -O binary $< $@
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard ; rm mongoose.[ch] ; ln -s ../../../../mongoose.c ; ln -s ../../../../mongoose.h
|
||||||
|
|
||||||
firmware.elf: FreeRTOS-Kernel cmsis_core cmsis_mcu $(SOURCES) hal.h link_ram.ld link.ld mongoose_config.h
|
|
||||||
arm-none-eabi-gcc $(SOURCES) $(wildcard FreeRTOS-Kernel/*.c) $(CFLAGS) $(LDFLAGS) -o $@
|
|
||||||
|
|
||||||
flash: firmware.bin
|
|
||||||
# flash
|
|
||||||
|
|
||||||
cmsis_core: # ARM CMSIS core headers
|
|
||||||
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
|
||||||
cmsis_mcu:
|
|
||||||
curl -sL https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1021_DFP.17.0.0.pack -o $@.zip
|
|
||||||
mkdir $@ && cd $@ && unzip -q ../$@.zip
|
|
||||||
FreeRTOS-Kernel: # FreeRTOS sources
|
|
||||||
git clone --depth 1 -b V10.5.0 https://github.com/FreeRTOS/FreeRTOS-Kernel $@
|
|
||||||
|
|
||||||
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/4
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/4
|
||||||
update: firmware.bin
|
update: firmware.bin
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
update updateram: CFLAGS += -DUART_DEBUG=LPUART2
|
test update: CFLAGS_EXTRA ="-DUART_DEBUG=LPUART2"
|
||||||
|
|
||||||
test: update
|
test: update
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=15 | tee /tmp/output.txt
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
|
|
||||||
updateram: ram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @firmware.bin
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0003 wm,e000edfc,1 wm,e000ed0c,5fa0004"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
PC=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,4"}' | jq -r .resp[5:]` && \
|
|
||||||
SP=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,0"}' | jq -r .resp[5:]` && \
|
|
||||||
REQ="wm,e000ed08,0 wr,d,$$SP wr,f,$$PC" && \
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"'"$$REQ"'"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0001"}'
|
|
||||||
|
|
||||||
testram: updateram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) firmware.* *.su cmsis_core cmsis_mcu FreeRTOS-Kernel *.zip
|
rm -rf firmware.* wizard*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=rt1020&ide=GCC+make&rtos=FreeRTOS&file=README.md)
|
||||||
@@ -1 +0,0 @@
|
|||||||
../rt1020-evk-make-baremetal-builtin/dcd.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../rt1020-evk-make-baremetal-builtin/flash_image.c
|
|
||||||
@@ -1,337 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
// https://www.nxp.com/webapp/Download?colCode=IMXRT1020RM
|
|
||||||
// https://cache.nxp.com/secured/assets/documents/en/user-guide/MIMXRT1020EVKHUG.pdf
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "MIMXRT1021.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BIT(x) (1UL << (x))
|
|
||||||
#define SETBITS(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK)
|
|
||||||
#define PIN(bank, num) ((((bank) - '0') << 8) | (num))
|
|
||||||
#define PINNO(pin) (pin & 255)
|
|
||||||
#define PINBANK(pin) (pin >> 8)
|
|
||||||
|
|
||||||
// Use LED for blinking, GPIO_AD_B0_05. GPIO1.5 (schematics)
|
|
||||||
#define LED PIN('1', 5)
|
|
||||||
|
|
||||||
#ifndef UART_DEBUG
|
|
||||||
#define UART_DEBUG LPUART1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// No settable constants, see sysinit.c
|
|
||||||
#define SYS_FREQUENCY 500000000UL
|
|
||||||
|
|
||||||
static inline void spin(volatile uint32_t count) {
|
|
||||||
while (count--) (void) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { CLOCK_OFF = 0U, CLOCK_ON_RUN = 1U, CLOCK_ON_RUN_WAIT = 3U };
|
|
||||||
static inline void clock_periph(uint32_t index, uint32_t shift, uint32_t val) {
|
|
||||||
volatile uint32_t *r = &CCM->CCGR0;
|
|
||||||
SETBITS(r[index], 3UL << shift, val << shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
// which peripheral feeds the pin
|
|
||||||
static inline void gpio_mux_config(uint16_t index, uint8_t af) {
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[index] = af;
|
|
||||||
}
|
|
||||||
|
|
||||||
// which pin feeds the peripheral (2nd stage)
|
|
||||||
static inline void periph_mux_config(uint16_t index, uint8_t in) {
|
|
||||||
IOMUXC->SELECT_INPUT[index] = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT };
|
|
||||||
enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN };
|
|
||||||
enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_MEDIUM_, GPIO_SPEED_HIGH };
|
|
||||||
enum { GPIO_PULL_NONE, GPIO_PULL_DOWN, GPIO_PULL_UP };
|
|
||||||
static inline GPIO_Type *gpio_bank(uint16_t pin) {
|
|
||||||
static const GPIO_Type *g[] = {NULL, GPIO1, GPIO2, GPIO3, NULL, GPIO5};
|
|
||||||
return (GPIO_Type *) g[PINBANK(pin)];
|
|
||||||
}
|
|
||||||
|
|
||||||
// pin driver/pull-up/down configuration (ignore "keeper")
|
|
||||||
static inline void gpio_pad_config(uint16_t index, uint8_t type, uint8_t speed,
|
|
||||||
uint8_t pull) {
|
|
||||||
bool dopull = pull > 0;
|
|
||||||
if (dopull) --pull;
|
|
||||||
IOMUXC->SW_PAD_CTL_PAD[index] =
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_ODE(type) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SRE(speed >= GPIO_SPEED_HIGH) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUE(1) | IOMUXC_SW_PAD_CTL_PAD_PKE(dopull) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUS(pull) | IOMUXC_SW_PAD_CTL_PAD_DSE(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
|
|
||||||
uint8_t speed, uint8_t pull) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint8_t bit = (uint8_t) PINNO(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
switch (PINBANK(pin)) {
|
|
||||||
case 1:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(1, CCM_CCGR1_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(0, CCM_CCGR0_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_mux_config(bit < 13
|
|
||||||
? kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32 + bit
|
|
||||||
: kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 + bit - 13,
|
|
||||||
5);
|
|
||||||
gpio_pad_config(bit < 13
|
|
||||||
? kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_32 + bit
|
|
||||||
: kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_00 + bit - 13,
|
|
||||||
type, speed, pull);
|
|
||||||
clock_periph(2, CCM_CCGR2_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// TODO(): support sw_mux
|
|
||||||
clock_periph(1, CCM_CCGR1_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio->IMR &= ~mask;
|
|
||||||
if (mode == GPIO_MODE_INPUT) {
|
|
||||||
gpio->GDIR &= ~mask;
|
|
||||||
} else {
|
|
||||||
gpio->GDIR |= mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_input(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
static inline void gpio_output(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool gpio_read(uint16_t pin) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
return gpio->DR & mask;
|
|
||||||
}
|
|
||||||
static inline void gpio_write(uint16_t pin, bool value) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
if (value) {
|
|
||||||
gpio->DR |= mask;
|
|
||||||
} else {
|
|
||||||
gpio->DR &= ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_toggle(uint16_t pin) {
|
|
||||||
gpio_write(pin, !gpio_read(pin));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 14.5 Table 14-4: uart_clk_root
|
|
||||||
// see sysinit.c for clocks, (14.7.9: defaults to PLL3/6/1 = 80MHz)
|
|
||||||
static inline void uart_init(LPUART_Type *uart, unsigned long baud) {
|
|
||||||
uint8_t af = 2; // Alternate function
|
|
||||||
uint16_t mr = 0, pr = 0, mt = 0, pt = 0; // pins
|
|
||||||
uint32_t freq = 80000000; // uart_clk_root frequency
|
|
||||||
if (uart == LPUART1)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_06,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_06,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_07,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_07;
|
|
||||||
if (uart == LPUART2)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_08,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_09,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09;
|
|
||||||
|
|
||||||
if (uart == LPUART1) clock_periph(5, CCM_CCGR5_CG12_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
if (uart == LPUART2) clock_periph(0, CCM_CCGR0_CG14_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(mt, af);
|
|
||||||
gpio_pad_config(pt, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(mr, af);
|
|
||||||
gpio_pad_config(pr, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
uart->GLOBAL |= LPUART_GLOBAL_RST_MASK; // reset, CTRL = 0, defaults
|
|
||||||
uart->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
|
|
||||||
SETBITS(uart->BAUD,
|
|
||||||
LPUART_BAUD_OSR_MASK | LPUART_BAUD_SBR_MASK | LPUART_BAUD_SBNS_MASK,
|
|
||||||
LPUART_BAUD_OSR(16 - 1) |
|
|
||||||
LPUART_BAUD_SBR(freq / (16 * baud))); // Rx sample at 16x
|
|
||||||
SETBITS(uart->CTRL,
|
|
||||||
LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK |
|
|
||||||
LPUART_CTRL_IDLECFG_MASK,
|
|
||||||
LPUART_CTRL_IDLECFG(1) | LPUART_CTRL_ILT(1) |
|
|
||||||
LPUART_BAUD_SBNS(0)); // no parity, idle 2 chars after 1 stop bit
|
|
||||||
uart->CTRL |= LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void uart_write_byte(LPUART_Type *uart, uint8_t byte) {
|
|
||||||
uart->DATA = byte;
|
|
||||||
while ((uart->STAT & LPUART_STAT_TDRE_MASK) == 0) spin(1);
|
|
||||||
}
|
|
||||||
static inline void uart_write_buf(LPUART_Type *uart, char *buf, size_t len) {
|
|
||||||
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
|
|
||||||
}
|
|
||||||
static inline int uart_read_ready(LPUART_Type *uart) {
|
|
||||||
(void) uart;
|
|
||||||
return uart->STAT & LPUART_STAT_RDRF_MASK;
|
|
||||||
}
|
|
||||||
static inline uint8_t uart_read_byte(LPUART_Type *uart) {
|
|
||||||
return (uint8_t) (uart->DATA & 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rng_init(void) {
|
|
||||||
clock_periph(6, CCM_CCGR6_CG6_SHIFT, CLOCK_ON_RUN_WAIT); // trng_clk
|
|
||||||
SETBITS(TRNG->MCTL,
|
|
||||||
TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK | TRNG_MCTL_RST_DEF_MASK,
|
|
||||||
TRNG_MCTL_PRGM(1) | TRNG_MCTL_ERR(1) |
|
|
||||||
TRNG_MCTL_RST_DEF(1)); // reset to default values
|
|
||||||
SETBITS(TRNG->MCTL, TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK,
|
|
||||||
TRNG_MCTL_PRGM(0)); // set to run mode
|
|
||||||
(void) TRNG->ENT[TRNG_ENT_COUNT - 1]; // start new entropy generation
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
}
|
|
||||||
static inline uint32_t rng_read(void) {
|
|
||||||
static uint8_t idx = 0;
|
|
||||||
while ((TRNG->MCTL & TRNG_MCTL_ENT_VAL_MASK) == 0) (void) 0;
|
|
||||||
uint32_t data = TRNG->ENT[idx++]; // read data
|
|
||||||
idx %= TRNG_ENT_COUNT; // stay within array limits
|
|
||||||
if (idx == 0) // we've just read TRNG_ENT_COUNT - 1
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - PHY has no xtal, XI driven from ENET_REF_CLK1 (labeled as ENET_TX_CLK
|
|
||||||
// (GPIO_AD_B0_08)), generated by the MCU
|
|
||||||
// - PHY RST connected to GPIO1.4 (GPIO_AD_B0_04); INTRP/NAND_TREE connected to
|
|
||||||
// GPIO1.22 (GPIO_AD_B1_06)
|
|
||||||
// - 37.4 REF_CLK1 is RMII mode reference clock for Rx, Tx, and SMI; it is I/O
|
|
||||||
// - 11.4.2 IOMUXC_GPR_GPR1 bit 17: ENET_REF_CLK_DIR --> 1 ENET_REF_CLK is
|
|
||||||
// output driven by ref_enetpll0
|
|
||||||
// - 14.6.1.3.4 Ethernet PLL (PLL6)
|
|
||||||
static inline void ethernet_init(void) {
|
|
||||||
gpio_init(PIN('1', 4), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP); // set GPIO1.4 as GPIO (PHY \RST)
|
|
||||||
gpio_write(PIN('1', 4), 0); // reset PHY
|
|
||||||
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_08,
|
|
||||||
4); // set for ENET_REF_CLK1
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_08] |=
|
|
||||||
IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RMII_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_08, so RMII clock is taken
|
|
||||||
// from ENET_REF_CLK1
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_08, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_09, 0); // set for RXDATA1
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_DATA1_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_09
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_09, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_10, 0); // set for RXDATA0
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_DATA0_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_10
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_10, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_11, 0); // set for CRS
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_EN_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_11
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_11, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12, 0); // set for RXERR
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RX_ERR_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_12
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_12, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13, 0); // set for TXEN
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_13, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_14, 0); // set for TXDATA0
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_14, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_15, 0); // set for TXDATA1
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_15, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_40, 4); // set for MDIO
|
|
||||||
periph_mux_config(kIOMUXC_ENET_MDIO_SELECT_INPUT,
|
|
||||||
2); // drive peripheral from EMC_40
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_40, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_41, 4); // set for MDC
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_41, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
gpio_init(PIN('1', 22), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // set GPIO1.22 as GPIO (PHY INTRP/NAND_TREE)
|
|
||||||
gpio_write(PIN('1', 22), 1); // prevent NAND_TREE
|
|
||||||
// 14.8.9 Use 500MHz reference and generate 50MHz. This is done at sysinit.c,
|
|
||||||
// as we use this source to clock the core
|
|
||||||
spin(10000); // keep PHY RST low for a while
|
|
||||||
gpio_write(PIN('1', 4), 1); // deassert RST
|
|
||||||
gpio_init(PIN('1', 22), GPIO_MODE_INPUT, 0, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // setup IRQ (pulled-up)(not used)
|
|
||||||
|
|
||||||
IOMUXC_GPR->GPR1 |=
|
|
||||||
IOMUXC_GPR_GPR1_ENET_REF_CLK_DIR(1); // Set ENET_REF_CLK1 as output
|
|
||||||
clock_periph(1, CCM_CCGR1_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enet_ipg_clk
|
|
||||||
NVIC_EnableIRQ(ENET_IRQn); // Setup Ethernet IRQ handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper macro for MAC generation, byte reads not allowed
|
|
||||||
#define GENERATE_LOCALLY_ADMINISTERED_MAC() \
|
|
||||||
{ \
|
|
||||||
2, OCOTP->CFG0 & 255, (OCOTP->CFG0 >> 10) & 255, \
|
|
||||||
((OCOTP->CFG0 >> 19) ^ (OCOTP->CFG1 >> 19)) & 255, \
|
|
||||||
(OCOTP->CFG1 >> 10) & 255, OCOTP->CFG1 & 255 \
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void flash_init(void) { // QSPI in FlexSPI
|
|
||||||
// set pins
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05, 1); // set for DQS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_05, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11, 1); // set for SS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_11, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07, 1); // set for SCLK
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_SCLK_SELECT_INPUT, 0); // drive peripheral from B1_07
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_07, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08, 1); // set for DATA0
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA0_SELECT_INPUT, 0); // drive peripheral from B1_08
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_08, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10, 1); // set for DATA1
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA1_SELECT_INPUT, 0); // drive peripheral from B1_10
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_10, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09, 1); // set for DATA2
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA2_SELECT_INPUT, 0); // drive peripheral from B1_09
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_09, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06, 1); // set for DATA3
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPI_A_DATA3_SELECT_INPUT, 0); // drive peripheral from B1_06
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_06, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
// set FlexSPI clock
|
|
||||||
SETBITS(CCM->CSCMR1, CCM_CSCMR1_FLEXSPI_CLK_SEL_MASK | CCM_CSCMR1_FLEXSPI_PODF_MASK, CCM_CSCMR1_FLEXSPI_CLK_SEL(3) | CCM_CSCMR1_FLEXSPI_PODF(3)); // select PLL3 PFD0 /4
|
|
||||||
clock_periph(6, CCM_CCGR6_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enable
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
ENTRY(Reset_Handler);
|
|
||||||
MEMORY {
|
|
||||||
flash_hdr(rx) : ORIGIN = 0x60000000, LENGTH = 8k
|
|
||||||
flash_irq(rx) : ORIGIN = 0x60002000, LENGTH = 1k
|
|
||||||
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8183k
|
|
||||||
|
|
||||||
itcram(rx) : ORIGIN = 0x00000000, LENGTH = 64k
|
|
||||||
dtcram(rw) : ORIGIN = 0x20000000, LENGTH = 64k
|
|
||||||
ocram(rw) : ORIGIN = 0x20200000, LENGTH = 128k
|
|
||||||
}
|
|
||||||
__StackTop = ORIGIN(dtcram) + LENGTH(dtcram);
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
.hdr : { FILL(0xff) ; KEEP(*(.cfg)) . = 0x1000 ; KEEP(*(.ivt)) . = 0x1020 ;
|
|
||||||
KEEP(*(.dat)) . = 0x1030 ; KEEP(*(.dcd)) . = 0x2000 ;} >flash_hdr
|
|
||||||
.irq : { KEEP(*(.isr_vector)) } > flash_irq
|
|
||||||
.text : { *(.text* .text.*) *(.rodata*) ; } > flash_code
|
|
||||||
.data : { __data_start__ = .; *(.data SORT(.data.*)) __data_end__ = .; } > dtcram AT > flash_code
|
|
||||||
__etext = LOADADDR(.data);
|
|
||||||
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > dtcram
|
|
||||||
_end = .;
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "mongoose.h"
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
|
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
|
||||||
uint32_t r = rng_read();
|
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
struct mg_tcpip_if *ifp = arg; // And show
|
|
||||||
const char *names[] = {"down", "up", "req", "ready"}; // network stats
|
|
||||||
MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
|
||||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
|
||||||
ifp->ndrop, ifp->nerr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void server(void *args) {
|
|
||||||
struct mg_mgr mgr; // Initialise Mongoose event manager
|
|
||||||
mg_mgr_init(&mgr); // and attach it to the interface
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
|
|
||||||
// Initialise Mongoose network stack
|
|
||||||
ethernet_init();
|
|
||||||
struct mg_tcpip_driver_imxrt_data driver_data = {.mdc_cr = 24, .phy_addr = 2};
|
|
||||||
struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC(),
|
|
||||||
// Uncomment below for static configuration:
|
|
||||||
// .ip = mg_htonl(MG_U32(192, 168, 0, 223)),
|
|
||||||
// .mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
|
||||||
// .gw = mg_htonl(MG_U32(192, 168, 0, 1)),
|
|
||||||
.driver = &mg_tcpip_driver_imxrt,
|
|
||||||
.driver_data = &driver_data};
|
|
||||||
mg_tcpip_init(&mgr, &mif);
|
|
||||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif);
|
|
||||||
|
|
||||||
MG_INFO(("MAC: %M. Waiting for IP...", mg_print_mac, mif.mac));
|
|
||||||
while (mif.state != MG_TCPIP_STATE_READY) {
|
|
||||||
mg_mgr_poll(&mgr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MG_INFO(("Initialising application..."));
|
|
||||||
web_init(&mgr);
|
|
||||||
|
|
||||||
MG_INFO(("Starting event loop"));
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1); // Infinite event loop
|
|
||||||
(void) args;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void blinker(void *args) {
|
|
||||||
gpio_output(LED); // Setup blue LED
|
|
||||||
for (;;) {
|
|
||||||
gpio_toggle(LED);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(BLINK_PERIOD_MS));
|
|
||||||
}
|
|
||||||
(void) args;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
uart_init(UART_DEBUG, 115200); // Initialise UART
|
|
||||||
|
|
||||||
// Start tasks. NOTE: stack sizes are in 32-bit words
|
|
||||||
xTaskCreate(blinker, "blinker", 128, ":)", configMAX_PRIORITIES - 1, NULL);
|
|
||||||
xTaskCreate(server, "server", 2048, 0, configMAX_PRIORITIES - 1, NULL);
|
|
||||||
|
|
||||||
vTaskStartScheduler(); // This blocks
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <errno.h> // we are not using lwIP
|
|
||||||
|
|
||||||
// See https://mongoose.ws/documentation/#build-options
|
|
||||||
#define MG_ARCH MG_ARCH_FREERTOS
|
|
||||||
|
|
||||||
#define MG_ENABLE_TCPIP 1
|
|
||||||
#define MG_ENABLE_DRIVER_IMXRT 1
|
|
||||||
#define MG_IO_SIZE 256
|
|
||||||
#define MG_ENABLE_CUSTOM_RANDOM 1
|
|
||||||
#define MG_ENABLE_PACKED_FS 1
|
|
||||||
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
int _fstat(int fd, struct stat *st) {
|
|
||||||
if (fd < 0) return -1;
|
|
||||||
st->st_mode = S_IFCHR;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *_sbrk(int incr) {
|
|
||||||
extern char _end;
|
|
||||||
static unsigned char *heap = NULL;
|
|
||||||
unsigned char *prev_heap;
|
|
||||||
if (heap == NULL) heap = (unsigned char *) &_end;
|
|
||||||
prev_heap = heap;
|
|
||||||
heap += incr;
|
|
||||||
return prev_heap;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _open(const char *path) {
|
|
||||||
(void) path;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _close(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isatty(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _lseek(int fd, int ptr, int dir) {
|
|
||||||
(void) fd, (void) ptr, (void) dir;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _exit(int status) {
|
|
||||||
(void) status;
|
|
||||||
for (;;) asm volatile("BKPT #0");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _kill(int pid, int sig) {
|
|
||||||
(void) pid, (void) sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getpid(void) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _write(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _read(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _link(const char *a, const char *b) {
|
|
||||||
(void) a, (void) b;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _unlink(const char *a) {
|
|
||||||
(void) a;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _stat(const char *path, struct stat *st) {
|
|
||||||
(void) path, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode) {
|
|
||||||
(void) path, (void) mode;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(void) {}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// This file contains essentials required by the CMSIS:
|
|
||||||
// uint32_t SystemCoreClock - holds the system core clock value
|
|
||||||
// SystemInit() - initialises the system, e.g. sets up clocks
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
uint32_t SystemCoreClock = SYS_FREQUENCY;
|
|
||||||
|
|
||||||
// - 14.4, Figure 14-2: clock tree
|
|
||||||
// - 14.7.4: ARM_PODF defaults to /1
|
|
||||||
// - 14.7.5: AHB_PODF defaults to /1; PERIPH_CLK_SEL defaults to derive clock
|
|
||||||
// from pre_periph_clk_sel
|
|
||||||
// - 14.7.6: PRE_PERIPH_CLK_SEL defaults to derive clock from PLL2 PFD3.
|
|
||||||
// - (For 528MHz operation, we need to set it to derive clock from PLL2, but
|
|
||||||
// this chip max is 500 MHz).
|
|
||||||
// - 14.6.1.3.1 System PLL (PLL2); 13.3.2.2 PLLs; 14.6.1.4 Phase Fractional
|
|
||||||
// Dividers (PFD)
|
|
||||||
// - 14.8.2: PLL2 is powered off and bypassed to 24MHz
|
|
||||||
// - 14.8.11: PFD defaults to 18/16 but Figure 14-2 shows half the value
|
|
||||||
// ("divider")
|
|
||||||
// - For 500MHz operation, we need to set PRE_PERIPH_CLK_SEL to derive clock
|
|
||||||
// from divided PLL6
|
|
||||||
// - 14.8.9: configure PLL6 to generate a 500MHz clock
|
|
||||||
// - Datasheet 4.1.3: System frequency/Bus frequency max 500/125MHz respectively
|
|
||||||
// (AHB/IPG)
|
|
||||||
// - MCUXpresso: IPG_CLK_ROOT <= 125MHz; PERCLK_CLK_ROOT <= 62.5MHz
|
|
||||||
// - Datasheet 4.8.4.1.1/2: the processor clock frequency must exceed twice the
|
|
||||||
// ENET_RX_CLK/ENET_TX_CLK frequency.
|
|
||||||
// - Datasheet 4.8.4.2: no details for RMII (above is for MII), assumed 50MHz
|
|
||||||
// min processor clock
|
|
||||||
// - Datasheet 4.1.3, Table 11: "Overdrive" run mode requires 1.25V core voltage
|
|
||||||
// minimum
|
|
||||||
void SystemInit(void) { // Called automatically by startup code (ints masked)
|
|
||||||
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU
|
|
||||||
asm("DSB");
|
|
||||||
asm("ISB");
|
|
||||||
// 53.4.2: Disable watchdog after reset (unlocked)
|
|
||||||
RTWDOG->CS &= ~RTWDOG_CS_EN_MASK;
|
|
||||||
RTWDOG->TOVAL = 0xFFFF;
|
|
||||||
while (RTWDOG->CS & RTWDOG_CS_ULK_MASK) spin(1); // wait for lock
|
|
||||||
while ((RTWDOG->CS & RTWDOG_CS_RCS_MASK) == 0)
|
|
||||||
spin(1); // wait for new config
|
|
||||||
// Set VDD_SOC to 1.25V
|
|
||||||
SETBITS(DCDC->REG3, DCDC_REG3_TRG_MASK, DCDC_REG3_TRG(0x12));
|
|
||||||
while ((DCDC->REG0 & DCDC_REG0_STS_DC_OK_MASK) == 0)
|
|
||||||
spin(1); // Wait for DCDC_STS_DC_OK
|
|
||||||
// 14.8.9 Init 500MHz reference, clock the M7 core with it, generate 50MHz for
|
|
||||||
// ENET and RMII.
|
|
||||||
SETBITS(CCM_ANALOG->PLL_ENET, CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_MASK |
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(0)); // bypass to 24MHz osc
|
|
||||||
SETBITS(
|
|
||||||
CCM_ANALOG->PLL_ENET,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT(1) | CCM_ANALOG_PLL_ENET_ENABLE_MASK |
|
|
||||||
CCM_ANALOG_PLL_ENET_ENET_500M_REF_EN_MASK); // setup PLL
|
|
||||||
while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_ENET &=
|
|
||||||
~CCM_ANALOG_PLL_ENET_BYPASS_MASK; // Disable Bypass (switch to PLL)
|
|
||||||
SETBITS(CCM->CBCDR, CCM_CBCDR_IPG_PODF_MASK,
|
|
||||||
CCM_CBCDR_IPG_PODF(3)); // Set IPG divider /4 (125MHz)
|
|
||||||
SETBITS(CCM->CSCMR1, CCM_CSCMR1_PERCLK_PODF_MASK,
|
|
||||||
CCM_CSCMR1_PERCLK_PODF(1)); // Set PERCLK divider /2 (62.5MHz)
|
|
||||||
SETBITS(CCM->CBCMR, CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK,
|
|
||||||
CCM_CBCMR_PRE_PERIPH_CLK_SEL(3)); // run from 500MHz clock
|
|
||||||
// 14.5 Table 14-4: uart_clk_root
|
|
||||||
// 14.4: uart_clk_root = PLL3/6 or OSC; CCM_CSCDR1 (14.7.9) defaults to
|
|
||||||
// PLL3/6/1; but ROM boot code fiddles with the divider (9.5.3 Table 9-7)
|
|
||||||
CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_POWER_MASK; // Power PLL on
|
|
||||||
while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_USB1 &=
|
|
||||||
~CCM_ANALOG_PLL_USB1_BYPASS_MASK; // Disable Bypass (switch to PLL)
|
|
||||||
CCM->CSCDR1 &= ~(CCM_CSCDR1_UART_CLK_SEL_MASK | CCM_CSCDR1_UART_CLK_PODF_MASK);
|
|
||||||
rng_init(); // Initialise random number generator
|
|
||||||
// NXP startup code calls SystemInit BEFORE initializing RAM...
|
|
||||||
SysTick_Config(SYS_FREQUENCY / 1000); // Sys tick every 1ms
|
|
||||||
}
|
|
||||||
@@ -1,85 +1,29 @@
|
|||||||
CFLAGS = -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion
|
BOARD = rt1060
|
||||||
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
|
IDE = GCC+make
|
||||||
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
|
RTOS = baremetal
|
||||||
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1062
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
CFLAGS += -Icmsis_mcu/devices/MIMXRT1062/drivers -DCPU_MIMXRT1062DVL6B
|
|
||||||
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 $(CFLAGS_EXTRA)
|
|
||||||
LDSCRIPT = link.ld
|
|
||||||
LDFLAGS ?= -T$(LDSCRIPT) -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
|
||||||
|
|
||||||
SOURCES = main.c syscalls.c sysinit.c
|
|
||||||
SOURCES += cmsis_mcu/devices/MIMXRT1062/gcc/startup_MIMXRT1062.S # NXP startup file. Compiler-dependent!
|
|
||||||
CFLAGS += -D__ATOLLIC__ -D__STARTUP_CLEAR_BSS # Make startup code work as expected
|
|
||||||
|
|
||||||
# Mongoose options are defined in mongoose_config.h
|
|
||||||
SOURCES += mongoose.c net.c packed_fs.c
|
|
||||||
|
|
||||||
# Example specific build options. See README.md
|
|
||||||
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\" -DHTTPS_URL=\"https://0.0.0.0/\"
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
|
||||||
RM = cmd /C del /Q /F /S
|
|
||||||
else
|
|
||||||
RM = rm -rf
|
|
||||||
endif
|
|
||||||
|
|
||||||
all build example update: SOURCES += flash_image.c
|
|
||||||
all build example: firmware.bin
|
all build example: firmware.bin
|
||||||
|
|
||||||
ram: LDSCRIPT = link_ram.ld
|
firmware.bin: wizard
|
||||||
ram: firmware.bin
|
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
|
||||||
|
|
||||||
firmware.bin: firmware.elf
|
wizard:
|
||||||
arm-none-eabi-objcopy -O binary $< $@
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard ; rm mongoose.[ch] ; ln -s ../../../../mongoose.c ; ln -s ../../../../mongoose.h
|
||||||
|
|
||||||
firmware.elf: cmsis_core cmsis_mcu $(SOURCES) hal.h link_ram.ld link.ld Makefile
|
|
||||||
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
|
|
||||||
arm-none-eabi-size $@
|
|
||||||
|
|
||||||
flash: firmware.bin
|
|
||||||
# flash
|
|
||||||
|
|
||||||
cmsis_core: # ARM CMSIS core headers
|
|
||||||
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
|
||||||
cmsis_mcu:
|
|
||||||
curl -sL https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1062_DFP.17.1.0.pack -o $@.zip
|
|
||||||
mkdir $@ && cd $@ && unzip -q ../$@.zip
|
|
||||||
mbedtls: # mbedTLS library
|
|
||||||
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
|
|
||||||
|
|
||||||
ifeq ($(TLS), mbedtls)
|
|
||||||
CFLAGS += -DMG_TLS=MG_TLS_MBED -Wno-conversion -Imbedtls/include
|
|
||||||
CFLAGS += -DMBEDTLS_CONFIG_FILE=\"mbedtls_config.h\" mbedtls/library/*.c
|
|
||||||
firmware.elf: mbedtls
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/13
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/13
|
||||||
update: firmware.bin
|
update: firmware.bin
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
update updateram: CFLAGS += -DUART_DEBUG=LPUART3
|
test update: CFLAGS_EXTRA ="-DUART_DEBUG=LPUART3"
|
||||||
|
|
||||||
test: update
|
test: update
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=15 | tee /tmp/output.txt
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
|
|
||||||
updateram: ram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @firmware.bin
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0003 wm,e000edfc,1 wm,e000ed0c,5fa0004"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
PC=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,4"}' | jq -r .resp[5:]` && \
|
|
||||||
SP=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,0"}' | jq -r .resp[5:]` && \
|
|
||||||
REQ="wm,e000ed08,0 wr,d,$$SP wr,f,$$PC" && \
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"'"$$REQ"'"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0001"}'
|
|
||||||
|
|
||||||
testram: updateram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) firmware.* *.su cmsis_core cmsis_mcu mbedtls *.zip
|
rm -rf firmware.* wizard*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=rt1060&ide=GCC+make&rtos=baremetal&file=README.md)
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020-2021 NXP
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define __DCD_DATA \
|
|
||||||
0xD2, 0x04, 0x10, 0x41, 0xCC, 0x03, 0x8C, 0x04, 0x40, 0x0F, 0xC0, 0x68, \
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x6C, 0xFF, 0xFF, 0xFF, 0xFF, \
|
|
||||||
0x40, 0x0F, 0xC0, 0x70, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x74, \
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x78, 0xFF, 0xFF, 0xFF, 0xFF, \
|
|
||||||
0x40, 0x0F, 0xC0, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0F, 0xC0, 0x80, \
|
|
||||||
0xFF, 0xFF, 0xFF, 0xFF, 0x40, 0x0D, 0x80, 0x30, 0x00, 0x00, 0x20, 0x01, \
|
|
||||||
0x40, 0x0D, 0x81, 0x00, 0x10, 0x1D, 0x10, 0x1B, 0x40, 0x0F, 0xC0, 0x14, \
|
|
||||||
0x00, 0x01, 0x0D, 0x40, 0x40, 0x1F, 0x80, 0x14, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x18, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x1C, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x24, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x28, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x2C, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x34, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x38, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x40, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x48, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x4C, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x50, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x58, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x5C, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x60, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x64, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x68, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x70, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x74, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x7C, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x84, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x88, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x8C, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x90, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x94, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0x98, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xA0, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xA4, 0x00, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x1F, 0x80, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xAC, \
|
|
||||||
0x00, 0x00, 0x00, 0x00, 0x40, 0x1F, 0x80, 0xB0, 0x00, 0x00, 0x00, 0x10, \
|
|
||||||
0x40, 0x1F, 0x82, 0x04, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x08, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x0C, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x10, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x14, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x18, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x1C, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x20, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x24, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x28, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x2C, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x30, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x34, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x38, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x3C, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x40, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x44, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x48, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x4C, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x50, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x54, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x58, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x5C, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x60, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x64, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x68, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x6C, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x70, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x74, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x78, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x7C, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x80, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x84, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x88, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x8C, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x90, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0x94, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x98, \
|
|
||||||
0x00, 0x01, 0x10, 0xF9, 0x40, 0x1F, 0x82, 0x9C, 0x00, 0x01, 0x10, 0xF9, \
|
|
||||||
0x40, 0x1F, 0x82, 0xA0, 0x00, 0x01, 0x10, 0xF9, 0x40, 0x2F, 0x00, 0x00, \
|
|
||||||
0x10, 0x00, 0x00, 0x04, 0x40, 0x2F, 0x00, 0x08, 0x00, 0x00, 0x00, 0x81, \
|
|
||||||
0x40, 0x2F, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x81, 0x40, 0x2F, 0x00, 0x10, \
|
|
||||||
0x80, 0x00, 0x00, 0x1B, 0x40, 0x2F, 0x00, 0x14, 0x82, 0x00, 0x00, 0x1B, \
|
|
||||||
0x40, 0x2F, 0x00, 0x18, 0x84, 0x00, 0x00, 0x1B, 0x40, 0x2F, 0x00, 0x1C, \
|
|
||||||
0x86, 0x00, 0x00, 0x1B, 0x40, 0x2F, 0x00, 0x20, 0x90, 0x00, 0x00, 0x21, \
|
|
||||||
0x40, 0x2F, 0x00, 0x24, 0xA0, 0x00, 0x00, 0x19, 0x40, 0x2F, 0x00, 0x28, \
|
|
||||||
0xA8, 0x00, 0x00, 0x17, 0x40, 0x2F, 0x00, 0x2C, 0xA9, 0x00, 0x00, 0x1B, \
|
|
||||||
0x40, 0x2F, 0x00, 0x30, 0x00, 0x00, 0x00, 0x21, 0x40, 0x2F, 0x00, 0x04, \
|
|
||||||
0x00, 0x00, 0x79, 0xA8, 0x40, 0x2F, 0x00, 0x40, 0x00, 0x00, 0x0F, 0x31, \
|
|
||||||
0x40, 0x2F, 0x00, 0x44, 0x00, 0x65, 0x29, 0x22, 0x40, 0x2F, 0x00, 0x48, \
|
|
||||||
0x00, 0x01, 0x09, 0x20, 0x40, 0x2F, 0x00, 0x4C, 0x50, 0x21, 0x0A, 0x08, \
|
|
||||||
0x40, 0x2F, 0x00, 0x80, 0x00, 0x00, 0x00, 0x21, 0x40, 0x2F, 0x00, 0x84, \
|
|
||||||
0x00, 0x88, 0x88, 0x88, 0x40, 0x2F, 0x00, 0x94, 0x00, 0x00, 0x00, 0x02, \
|
|
||||||
0x40, 0x2F, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2F, 0x00, 0x90, \
|
|
||||||
0x80, 0x00, 0x00, 0x00, 0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0F, \
|
|
||||||
0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, \
|
|
||||||
0xCC, 0x00, 0x14, 0x04, 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0C, 0xCF, 0x00, 0x0C, 0x1C, \
|
|
||||||
0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0xCC, 0x00, 0x14, 0x04, \
|
|
||||||
0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, 0x40, 0x2F, 0x00, 0x9C, \
|
|
||||||
0xA5, 0x5A, 0x00, 0x0C, 0xCF, 0x00, 0x0C, 0x1C, 0x40, 0x2F, 0x00, 0x3C, \
|
|
||||||
0x00, 0x00, 0x00, 0x01, 0xCC, 0x00, 0x1C, 0x04, 0x40, 0x2F, 0x00, 0xA0, \
|
|
||||||
0x00, 0x00, 0x00, 0x33, 0x40, 0x2F, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, \
|
|
||||||
0x40, 0x2F, 0x00, 0x9C, 0xA5, 0x5A, 0x00, 0x0A, 0xCF, 0x00, 0x0C, 0x1C, \
|
|
||||||
0x40, 0x2F, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0xCC, 0x00, 0x0C, 0x04, \
|
|
||||||
0x40, 0x2F, 0x00, 0x4C, 0x50, 0x21, 0x0A, 0x09
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
#include "dcd.h" // pin settings for MIMXRT1060-EVKB board
|
|
||||||
#include "fsl_flexspi.h" // peripheral structures
|
|
||||||
#include "fsl_romapi.h" // peripheral structures
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
extern uint32_t __isr_vector[];
|
|
||||||
|
|
||||||
// RM 9.7.2
|
|
||||||
__attribute__((section(".dcd"), used))
|
|
||||||
const uint8_t __ivt_dcd_data[] = {__DCD_DATA};
|
|
||||||
|
|
||||||
// RM 9.7.1
|
|
||||||
__attribute__((section(".dat"), used)) const uint32_t __ivt_boot_data[] = {
|
|
||||||
FlexSPI_AMBA_BASE, // boot start location
|
|
||||||
8 * 1024 * 1024, // size
|
|
||||||
0, // Plugin flag
|
|
||||||
0Xffffffff // empty - extra data word
|
|
||||||
};
|
|
||||||
|
|
||||||
__attribute__((section(".ivt"), used)) const uint32_t __ivt[8] = {
|
|
||||||
0x412000d1, // header: 41 - version, 2000 size, d1 tag
|
|
||||||
(uint32_t) __isr_vector, // entry
|
|
||||||
0, // reserved
|
|
||||||
(uint32_t) __ivt_dcd_data, // dcd
|
|
||||||
(uint32_t) __ivt_boot_data, // boot data
|
|
||||||
(uint32_t) __ivt, // this is us - ivt absolute address
|
|
||||||
0, // csf absolute address
|
|
||||||
0, // reserved for HAB
|
|
||||||
};
|
|
||||||
|
|
||||||
#define __FLEXSPI_QSPI_LUT { \
|
|
||||||
[0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18), \
|
|
||||||
[1] = FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),\
|
|
||||||
[4 * 1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x04),\
|
|
||||||
[4 * 3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x06, STOP, FLEXSPI_1PAD, 0x0),\
|
|
||||||
[4 * 5 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x20, RADDR_SDR, FLEXSPI_1PAD, 0x18),\
|
|
||||||
[4 * 8 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xD8, RADDR_SDR, FLEXSPI_1PAD, 0x18),\
|
|
||||||
[4 * 9 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x02, RADDR_SDR, FLEXSPI_1PAD, 0x18),\
|
|
||||||
[4 * 9 + 1] = FLEXSPI_LUT_SEQ(WRITE_SDR, FLEXSPI_1PAD, 0x04, STOP, FLEXSPI_1PAD, 0x0),\
|
|
||||||
[4 * 11 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x60, STOP, FLEXSPI_1PAD, 0x0),\
|
|
||||||
}
|
|
||||||
|
|
||||||
// MIMXRT1060-EVKB flash chip config: IS25WP064AJBLE
|
|
||||||
__attribute__((section(".cfg"), used))
|
|
||||||
const flexspi_nor_config_t __qspi_flash_cfg = {
|
|
||||||
.memConfig = {.tag = FLEXSPI_CFG_BLK_TAG,
|
|
||||||
.version = FLEXSPI_CFG_BLK_VERSION,
|
|
||||||
.readSampleClkSrc = 1, // ReadSampleClk_LoopbackFromDqsPad
|
|
||||||
.csHoldTime = 3,
|
|
||||||
.csSetupTime = 3,
|
|
||||||
.controllerMiscOption = BIT(4),
|
|
||||||
.deviceType = 1, // serial NOR
|
|
||||||
.sflashPadType = 4,
|
|
||||||
.serialClkFreq = 7, // 120MHz
|
|
||||||
.sflashA1Size = 8 * 1024 * 1024,
|
|
||||||
.lookupTable = __FLEXSPI_QSPI_LUT},
|
|
||||||
.pageSize = 256,
|
|
||||||
.sectorSize = 4 * 1024,
|
|
||||||
.ipcmdSerialClkFreq = 1,
|
|
||||||
.blockSize = 64 * 1024,
|
|
||||||
.isUniformBlockSize = false};
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
// https://cache.nxp.com/secured/assets/documents/en/reference-manual/IMXRT1060XRM.pdf
|
|
||||||
// https://cache.nxp.com/secured/assets/documents/en/user-guide/MIMXRT1060EVKBUM.pdf
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "MIMXRT1062.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BIT(x) (1UL << (x))
|
|
||||||
#define SETBITS(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK)
|
|
||||||
#define PIN(bank, num) ((((bank) - '0') << 8) | (num))
|
|
||||||
#define PINNO(pin) (pin & 255)
|
|
||||||
#define PINBANK(pin) (pin >> 8)
|
|
||||||
|
|
||||||
// Use LED for blinking, D8: GPIO_AD_B0_08. GPIO1.8 (schematics, RM)
|
|
||||||
#define LED PIN('1', 8)
|
|
||||||
|
|
||||||
#ifndef UART_DEBUG
|
|
||||||
#define UART_DEBUG LPUART1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// No settable constants, see sysinit.c
|
|
||||||
#define SYS_FREQUENCY 600000000UL
|
|
||||||
|
|
||||||
static inline void spin(volatile uint32_t count) {
|
|
||||||
while (count--) (void) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { CLOCK_OFF = 0U, CLOCK_ON_RUN = 1U, CLOCK_ON_RUN_WAIT = 3U };
|
|
||||||
static inline void clock_periph(uint32_t index, uint32_t shift, uint32_t val) {
|
|
||||||
volatile uint32_t *r = &CCM->CCGR0;
|
|
||||||
SETBITS(r[index], 3UL << shift, val << shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
// which peripheral feeds the pin
|
|
||||||
static inline void gpio_mux_config(uint16_t index, uint8_t af) {
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[index] = af;
|
|
||||||
}
|
|
||||||
|
|
||||||
// which pin feeds the peripheral (2nd stage)
|
|
||||||
static inline void periph_mux_config(uint16_t index, uint8_t in) {
|
|
||||||
IOMUXC->SELECT_INPUT[index] = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT };
|
|
||||||
enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN };
|
|
||||||
enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_MEDIUM_, GPIO_SPEED_HIGH };
|
|
||||||
enum { GPIO_PULL_NONE, GPIO_PULL_DOWN, GPIO_PULL_UP };
|
|
||||||
static inline GPIO_Type *gpio_bank(uint16_t pin) {
|
|
||||||
static const GPIO_Type *g[] = {NULL, GPIO1, GPIO2, GPIO3, NULL, GPIO5};
|
|
||||||
return (GPIO_Type *) g[PINBANK(pin)];
|
|
||||||
}
|
|
||||||
|
|
||||||
// pin driver/pull-up/down configuration (ignore "keeper")
|
|
||||||
static inline void gpio_pad_config(uint16_t index, uint8_t type, uint8_t speed,
|
|
||||||
uint8_t pull) {
|
|
||||||
bool dopull = pull > 0;
|
|
||||||
if (dopull) --pull;
|
|
||||||
IOMUXC->SW_PAD_CTL_PAD[index] =
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_ODE(type) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SRE(speed >= GPIO_SPEED_HIGH) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUE(1) | IOMUXC_SW_PAD_CTL_PAD_PKE(dopull) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUS(pull) | IOMUXC_SW_PAD_CTL_PAD_DSE(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
|
|
||||||
uint8_t speed, uint8_t pull) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint8_t bit = (uint8_t) PINNO(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
switch (PINBANK(pin)) {
|
|
||||||
case 1:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(1, CCM_CCGR1_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(0, CCM_CCGR0_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_mux_config(bit < 12 ? kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_00 + bit
|
|
||||||
: bit < 18
|
|
||||||
? kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 + bit - 12
|
|
||||||
: kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32 + bit - 18,
|
|
||||||
5);
|
|
||||||
gpio_pad_config(bit < 12 ? kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_00 + bit
|
|
||||||
: bit < 18
|
|
||||||
? kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_00 + bit - 12
|
|
||||||
: kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_32 + bit - 18,
|
|
||||||
type, speed, pull);
|
|
||||||
clock_periph(2, CCM_CCGR2_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// TODO(): support sw_mux
|
|
||||||
clock_periph(1, CCM_CCGR1_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio->IMR &= ~mask;
|
|
||||||
if (mode == GPIO_MODE_INPUT) {
|
|
||||||
gpio->GDIR &= ~mask;
|
|
||||||
} else {
|
|
||||||
gpio->GDIR |= mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_input(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
static inline void gpio_output(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool gpio_read(uint16_t pin) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
return gpio->DR & mask;
|
|
||||||
}
|
|
||||||
static inline void gpio_write(uint16_t pin, bool value) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
if (value) {
|
|
||||||
gpio->DR |= mask;
|
|
||||||
} else {
|
|
||||||
gpio->DR &= ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_toggle(uint16_t pin) {
|
|
||||||
gpio_write(pin, !gpio_read(pin));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 14.5 Table 14-4: uart_clk_root
|
|
||||||
// see sysinit.c for clocks, (14.7.9: defaults to pll3_80m = PLL3/6/1 = 80MHz)
|
|
||||||
static inline void uart_init(LPUART_Type *uart, unsigned long baud) {
|
|
||||||
uint8_t af = 2; // Alternate function
|
|
||||||
uint16_t mr = 0, pr = 0, mt = 0, pt = 0; // pins
|
|
||||||
uint32_t freq = 80000000; // uart_clk_root frequency
|
|
||||||
if (uart == LPUART1)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_12,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_13;
|
|
||||||
if (uart == LPUART3)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_06,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07;
|
|
||||||
|
|
||||||
if (uart == LPUART1) clock_periph(5, CCM_CCGR5_CG12_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
if (uart == LPUART3) clock_periph(0, CCM_CCGR0_CG6_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(mt, af);
|
|
||||||
gpio_pad_config(pt, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(mr, af);
|
|
||||||
gpio_pad_config(pr, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
uart->GLOBAL |= LPUART_GLOBAL_RST_MASK; // reset, CTRL = 0, defaults
|
|
||||||
uart->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
|
|
||||||
SETBITS(uart->BAUD,
|
|
||||||
LPUART_BAUD_OSR_MASK | LPUART_BAUD_SBR_MASK | LPUART_BAUD_SBNS_MASK,
|
|
||||||
LPUART_BAUD_OSR(16 - 1) |
|
|
||||||
LPUART_BAUD_SBR(freq / (16 * baud))); // Rx sample at 16x
|
|
||||||
SETBITS(uart->CTRL,
|
|
||||||
LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK |
|
|
||||||
LPUART_CTRL_IDLECFG_MASK,
|
|
||||||
LPUART_CTRL_IDLECFG(1) | LPUART_CTRL_ILT(1) |
|
|
||||||
LPUART_BAUD_SBNS(0)); // no parity, idle 2 chars after 1 stop bit
|
|
||||||
uart->CTRL |= LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void uart_write_byte(LPUART_Type *uart, uint8_t byte) {
|
|
||||||
uart->DATA = byte;
|
|
||||||
while ((uart->STAT & LPUART_STAT_TDRE_MASK) == 0) spin(1);
|
|
||||||
}
|
|
||||||
static inline void uart_write_buf(LPUART_Type *uart, char *buf, size_t len) {
|
|
||||||
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
|
|
||||||
}
|
|
||||||
static inline int uart_read_ready(LPUART_Type *uart) {
|
|
||||||
(void) uart;
|
|
||||||
return uart->STAT & LPUART_STAT_RDRF_MASK;
|
|
||||||
}
|
|
||||||
static inline uint8_t uart_read_byte(LPUART_Type *uart) {
|
|
||||||
return (uint8_t) (uart->DATA & 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rng_init(void) {
|
|
||||||
clock_periph(6, CCM_CCGR6_CG6_SHIFT, CLOCK_ON_RUN_WAIT); // trng_clk
|
|
||||||
SETBITS(TRNG->MCTL,
|
|
||||||
TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK | TRNG_MCTL_RST_DEF_MASK,
|
|
||||||
TRNG_MCTL_PRGM(1) | TRNG_MCTL_ERR(1) |
|
|
||||||
TRNG_MCTL_RST_DEF(1)); // reset to default values
|
|
||||||
SETBITS(TRNG->MCTL, TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK,
|
|
||||||
TRNG_MCTL_PRGM(0)); // set to run mode
|
|
||||||
(void) TRNG->ENT[TRNG_ENT_COUNT - 1]; // start new entropy generation
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
}
|
|
||||||
static inline uint32_t rng_read(void) {
|
|
||||||
static uint8_t idx = 0;
|
|
||||||
while ((TRNG->MCTL & TRNG_MCTL_ENT_VAL_MASK) == 0) (void) 0;
|
|
||||||
uint32_t data = TRNG->ENT[idx++]; // read data
|
|
||||||
idx %= TRNG_ENT_COUNT; // stay within array limits
|
|
||||||
if (idx == 0) // we've just read TRNG_ENT_COUNT - 1
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - PHY has no xtal, XI driven from ENET_REF_CLK1 (labeled as ENET_TX_REF_CLK
|
|
||||||
// (GPIO_AD_B1_10)), generated by the MCU
|
|
||||||
// - PHY RST connected to GPIO1.9 (GPIO_AD_B0_09); INTRP/NAND_TREE connected to
|
|
||||||
// GPIO1.10 (GPIO_AD_B0_10)
|
|
||||||
// - 41.4 REF_CLK1 is RMII mode reference clock for Rx, Tx, and SMI; it is I/O
|
|
||||||
// - 11.3.2 IOMUXC_GPR_GPR1
|
|
||||||
// - bit 13: ENET1_CLK_SEL --> 0 ENET1 TX reference clock driven by
|
|
||||||
// ref_enetpll and output via ENET_REF_CLK1 (labeled as ENET_REF_CLK
|
|
||||||
// elsewhere)
|
|
||||||
// - bit 17: ENET1_TX_CLK_DIR --> 1 ENET1_TX_CLK output driver enabled
|
|
||||||
// - 14.6.1.3.6 Ethernet PLL (PLL6)
|
|
||||||
// - 14.8.14: configure PLL6 to generate 50MHz clocks for ENET and RMII.
|
|
||||||
static inline void ethernet_init(void) {
|
|
||||||
// setup PLL and clock ENET from it
|
|
||||||
SETBITS(CCM_ANALOG->PLL_ENET, CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_MASK |
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(0)); // bypass to 24MHz osc
|
|
||||||
SETBITS(
|
|
||||||
CCM_ANALOG->PLL_ENET,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT(1) | CCM_ANALOG_PLL_ENET_ENABLE_MASK);
|
|
||||||
while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_ENET &= ~CCM_ANALOG_PLL_ENET_BYPASS_MASK;
|
|
||||||
|
|
||||||
gpio_init(PIN('1', 9), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP); // set GPIO1.9 as GPIO (PHY \RST)
|
|
||||||
gpio_write(PIN('1', 9), 0); // reset PHY
|
|
||||||
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_10,
|
|
||||||
6); // set for ENET_REF_CLK
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_10] |=
|
|
||||||
IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_ENET_IPG_CLK_RMII_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_10, so RMII clock is taken
|
|
||||||
// from ENET_REF_CLK
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_10, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
IOMUXC_GPR->GPR1 |=
|
|
||||||
IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR(1); // Set ENET_TX_CLK as output
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_04, 3); // set for RXDATA0
|
|
||||||
periph_mux_config(kIOMUXC_ENET0_RXDATA_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_04
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_04, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_05, 3); // set for RXDATA1
|
|
||||||
periph_mux_config(kIOMUXC_ENET1_RXDATA_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_05
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_05, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_06, 3); // set for CRS
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RXEN_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_06
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_06, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_07, 3); // set for TXDATA0
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_07, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_08, 3); // set for TXDATA1
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_08, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_09, 3); // set for TXEN
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_09, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_11, 3); // set for RXERR
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RXERR_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_12
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_11, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_40, 4); // set for MDC
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_40, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_41, 4); // set for MDIO
|
|
||||||
periph_mux_config(kIOMUXC_ENET_MDIO_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from EMC_41
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_41, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
gpio_init(PIN('1', 10), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // set GPIO1.10 as GPIO (PHY INTRP/NAND_TREE)
|
|
||||||
gpio_write(PIN('1', 10), 1); // prevent NAND_TREE
|
|
||||||
spin(10000); // keep PHY RST low for a while
|
|
||||||
gpio_write(PIN('1', 9), 1); // deassert RST
|
|
||||||
gpio_init(PIN('1', 10), GPIO_MODE_INPUT, 0, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // setup IRQ (pulled-up)(not used)
|
|
||||||
|
|
||||||
clock_periph(1, CCM_CCGR1_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enet_ipg_clk
|
|
||||||
NVIC_EnableIRQ(ENET_IRQn); // Setup Ethernet IRQ handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper macro for MAC generation, byte reads not allowed
|
|
||||||
#define GENERATE_LOCALLY_ADMINISTERED_MAC() \
|
|
||||||
{ \
|
|
||||||
2, OCOTP->CFG0 & 255, (OCOTP->CFG0 >> 10) & 255, \
|
|
||||||
((OCOTP->CFG0 >> 19) ^ (OCOTP->CFG1 >> 19)) & 255, \
|
|
||||||
(OCOTP->CFG1 >> 10) & 255, OCOTP->CFG1 & 255 \
|
|
||||||
}
|
|
||||||
// NOTE: You can fuse your own MAC and read it from OCOTP->MAC0, OCOTP->MAC1,
|
|
||||||
// OCOTP->MAC2
|
|
||||||
|
|
||||||
static inline void flash_init(void) { // QSPI in FlexSPI
|
|
||||||
// set pins
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05, 1); // set for DQS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DQS_SELECT_INPUT, 0); // drive peripheral from B1_05
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_05, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06, 1); // set for SS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_06, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07, 1); // set for SCLK
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_SCK_SELECT_INPUT, 0); // drive peripheral from B1_07
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_07, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08, 1); // set for DATA0
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA0_SELECT_INPUT, 0); // drive peripheral from B1_08
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_08, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09, 1); // set for DATA1
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA1_SELECT_INPUT, 0); // drive peripheral from B1_09
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_09, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10, 1); // set for DATA2
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA2_SELECT_INPUT, 0); // drive peripheral from B1_10
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_10, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11, 1); // set for DATA3
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA3_SELECT_INPUT, 0); // drive peripheral from B1_11
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_11, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
// set FlexSPI clock
|
|
||||||
SETBITS(CCM->CSCMR1, CCM_CSCMR1_FLEXSPI_CLK_SEL_MASK | CCM_CSCMR1_FLEXSPI_PODF_MASK, CCM_CSCMR1_FLEXSPI_CLK_SEL(3) | CCM_CSCMR1_FLEXSPI_PODF(7)); // select PLL3 PFD0 /8
|
|
||||||
clock_periph(6, CCM_CCGR6_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enable
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
ENTRY(Reset_Handler);
|
|
||||||
MEMORY {
|
|
||||||
flash_hdr(rx) : ORIGIN = 0x60000000, LENGTH = 8k
|
|
||||||
flash_irq(rx) : ORIGIN = 0x60002000, LENGTH = 1k
|
|
||||||
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8183k
|
|
||||||
|
|
||||||
itcram(rx) : ORIGIN = 0x00000000, LENGTH = 128k
|
|
||||||
dtcram(rw) : ORIGIN = 0x20000000, LENGTH = 128k
|
|
||||||
ocram(rw) : ORIGIN = 0x20200000, LENGTH = 256k /* Is this cached ? */
|
|
||||||
}
|
|
||||||
__StackTop = ORIGIN(dtcram) + LENGTH(dtcram);
|
|
||||||
|
|
||||||
/* TODO(): separate itcram and go back to using dtcram for data and bss when ota is finished */
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
.hdr : { FILL(0xff) ; KEEP(*(.cfg)) . = 0x1000 ; KEEP(*(.ivt)) . = 0x1020 ;
|
|
||||||
KEEP(*(.dat)) . = 0x1030 ; KEEP(*(.dcd)) . = 0x2000 ;} >flash_hdr
|
|
||||||
.irq : { KEEP(*(.isr_vector)) } > flash_irq
|
|
||||||
.text : { *(.text* .text.*) *(.rodata*) ; } > flash_code
|
|
||||||
.data : { __data_start__ = .; *(.data SORT(.data.*)) *(.iram) __data_end__ = .; } > itcram AT > flash_code
|
|
||||||
__etext = LOADADDR(.data);
|
|
||||||
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > itcram
|
|
||||||
_end = .;
|
|
||||||
}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
// Copyright (c) 2022-2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "mongoose.h"
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
|
|
||||||
|
|
||||||
static volatile uint64_t s_ticks; // Milliseconds since boot
|
|
||||||
void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
|
|
||||||
s_ticks++;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t mg_millis(void) { // Let Mongoose use our uptime function
|
|
||||||
return s_ticks; // Return number of milliseconds since boot
|
|
||||||
}
|
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
|
||||||
uint32_t r = rng_read();
|
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
gpio_toggle(LED); // Blink LED
|
|
||||||
struct mg_tcpip_if *ifp = arg; // And show
|
|
||||||
const char *names[] = {"down", "up", "req", "ready"}; // network stats
|
|
||||||
MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
|
||||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
|
||||||
ifp->ndrop, ifp->nerr));
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
gpio_output(LED); // Setup blue LED
|
|
||||||
uart_init(UART_DEBUG, 115200); // Initialise debug printf
|
|
||||||
ethernet_init(); // Initialise ethernet pins
|
|
||||||
MG_INFO(("Starting, CPU freq %g MHz", (double) SystemCoreClock / 1000000));
|
|
||||||
|
|
||||||
struct mg_mgr mgr; // Initialise
|
|
||||||
mg_mgr_init(&mgr); // Mongoose event manager
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
|
|
||||||
// Initialise Mongoose network stack
|
|
||||||
struct mg_tcpip_driver_imxrt_data driver_data = {.mdc_cr = 24, .phy_addr = 2};
|
|
||||||
struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC(),
|
|
||||||
// Uncomment below for static configuration:
|
|
||||||
// .ip = mg_htonl(MG_U32(192, 168, 0, 223)),
|
|
||||||
// .mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
|
||||||
// .gw = mg_htonl(MG_U32(192, 168, 0, 1)),
|
|
||||||
.driver = &mg_tcpip_driver_imxrt,
|
|
||||||
.driver_data = &driver_data};
|
|
||||||
mg_tcpip_init(&mgr, &mif);
|
|
||||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif);
|
|
||||||
|
|
||||||
MG_INFO(("MAC: %M. Waiting for IP...", mg_print_mac, mif.mac));
|
|
||||||
while (mif.state != MG_TCPIP_STATE_READY) {
|
|
||||||
mg_mgr_poll(&mgr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MG_INFO(("Initialising application..."));
|
|
||||||
web_init(&mgr);
|
|
||||||
|
|
||||||
MG_INFO(("Starting event loop"));
|
|
||||||
for (;;) {
|
|
||||||
mg_mgr_poll(&mgr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// See https://mongoose.ws/documentation/#build-options
|
|
||||||
#define MG_ARCH MG_ARCH_NEWLIB
|
|
||||||
#define MG_OTA MG_OTA_FLASH
|
|
||||||
#define MG_DEVICE MG_DEVICE_RT1060
|
|
||||||
|
|
||||||
#define MG_ENABLE_TCPIP 1
|
|
||||||
#define MG_ENABLE_DRIVER_IMXRT 1
|
|
||||||
#define MG_IO_SIZE 256
|
|
||||||
#define MG_ENABLE_CUSTOM_MILLIS 1
|
|
||||||
#define MG_ENABLE_CUSTOM_RANDOM 1
|
|
||||||
#define MG_ENABLE_PACKED_FS 1
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../device-dashboard/net.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../device-dashboard/net.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../device-dashboard/packed_fs.c
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
int _fstat(int fd, struct stat *st) {
|
|
||||||
if (fd < 0) return -1;
|
|
||||||
st->st_mode = S_IFCHR;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *_sbrk(int incr) {
|
|
||||||
extern char _end;
|
|
||||||
static unsigned char *heap = NULL;
|
|
||||||
unsigned char *prev_heap;
|
|
||||||
unsigned char x = 0, *heap_end = (unsigned char *)((size_t) &x - 512);
|
|
||||||
(void) x;
|
|
||||||
if (heap == NULL) heap = (unsigned char *) &_end;
|
|
||||||
prev_heap = heap;
|
|
||||||
if (heap + incr > heap_end) return (void *) -1;
|
|
||||||
heap += incr;
|
|
||||||
return prev_heap;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _open(const char *path) {
|
|
||||||
(void) path;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _close(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isatty(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _lseek(int fd, int ptr, int dir) {
|
|
||||||
(void) fd, (void) ptr, (void) dir;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _exit(int status) {
|
|
||||||
(void) status;
|
|
||||||
for (;;) asm volatile("BKPT #0");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _kill(int pid, int sig) {
|
|
||||||
(void) pid, (void) sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getpid(void) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _write(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _read(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _link(const char *a, const char *b) {
|
|
||||||
(void) a, (void) b;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _unlink(const char *a) {
|
|
||||||
(void) a;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _stat(const char *path, struct stat *st) {
|
|
||||||
(void) path, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode) {
|
|
||||||
(void) path, (void) mode;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(void) {}
|
|
||||||
|
|
||||||
extern uint64_t mg_now(void);
|
|
||||||
|
|
||||||
int _gettimeofday(struct timeval *tv, void *tz) {
|
|
||||||
uint64_t now = mg_now();
|
|
||||||
(void) tz;
|
|
||||||
tv->tv_sec = (time_t) (now / 1000);
|
|
||||||
tv->tv_usec = (unsigned long) ((now % 1000) * 1000);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
//
|
|
||||||
// This file contains essentials required by the CMSIS:
|
|
||||||
// uint32_t SystemCoreClock - holds the system core clock value
|
|
||||||
// SystemInit() - initialises the system, e.g. sets up clocks
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
uint32_t SystemCoreClock = SYS_FREQUENCY;
|
|
||||||
|
|
||||||
// - 14.4, Figure 14-2: clock tree
|
|
||||||
// - 14.7.4: ARM_PODF defaults to /2; 9.5.3 Table 9-7: ROM agrees
|
|
||||||
// - 14.7.5: AHB_PODF defaults to /1; IPG_PODF defaults to /4; PERIPH_CLK_SEL
|
|
||||||
// defaults to derive clock from pre_periph_clk_sel
|
|
||||||
// - 9.5.3 Table 9-7: ROM changes IPG_PODF to /3
|
|
||||||
// - 14.7.6: PRE_PERIPH_CLK_SEL defaults to derive clock from divided
|
|
||||||
// PLL1; 9.5.3 Table 9-7: ROM agrees
|
|
||||||
// - (For 528MHz operation, we need to set it to derive clock from PLL2)
|
|
||||||
// - 14.7.7: PER_CLK defaults to IPG/1; 9.5.3 Table 9-7: ROM changes it to IPG/2
|
|
||||||
// - 14.6.1.3.1 ARM PLL (PLL1); 13.3.2.2 PLLs
|
|
||||||
// - 14.8.1: PLL1 is powered off and bypassed to 24MHz. Fout = 24MHz *
|
|
||||||
// div_select/2
|
|
||||||
// - 9.5.3 Table 9-7: ROM enables this PLL and sets it up
|
|
||||||
// - For 600MHz operation, we need to set PLL1 on
|
|
||||||
// - Datasheet 4.1.3: System frequency/Bus frequency max 600/150MHz respectively
|
|
||||||
// (AHB/IPG)
|
|
||||||
// - MCUXpresso: IPG_CLK_ROOT <= 150MHz; PERCLK_CLK_ROOT <= 75MHz
|
|
||||||
// - Datasheet 4.9.4.1.1/2: the processor clock frequency must exceed twice the
|
|
||||||
// ENET_RX_CLK/ENET_TX_CLK frequency.
|
|
||||||
// - Datasheet 4.9.4.2: no details for RMII (above is for MII), assumed 50MHz
|
|
||||||
// min processor clock
|
|
||||||
// - Datasheet 4.1.3, Table 10: "Overdrive" run mode requires 1.25V core voltage
|
|
||||||
// minimum; 528 MHz does not.
|
|
||||||
void SystemInit(void) { // Called automatically by startup code (ints masked)
|
|
||||||
SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU
|
|
||||||
asm("DSB");
|
|
||||||
asm("ISB");
|
|
||||||
// 58.4.2: Disable watchdog after reset (unlocked)
|
|
||||||
RTWDOG->CS &= ~RTWDOG_CS_EN_MASK;
|
|
||||||
RTWDOG->TOVAL = 0xFFFF;
|
|
||||||
while (RTWDOG->CS & RTWDOG_CS_ULK_MASK) spin(1); // wait for lock
|
|
||||||
while ((RTWDOG->CS & RTWDOG_CS_RCS_MASK) == 0)
|
|
||||||
spin(1); // wait for new config
|
|
||||||
// Set VDD_SOC to 1.25V
|
|
||||||
SETBITS(DCDC->REG3, DCDC_REG3_TRG_MASK, DCDC_REG3_TRG(0x12));
|
|
||||||
while ((DCDC->REG0 & DCDC_REG0_STS_DC_OK_MASK) == 0)
|
|
||||||
spin(1); // Wait for DCDC_STS_DC_OK
|
|
||||||
// ROM fiddles with AHB divider, wait and then keep bits at 0 (expected)
|
|
||||||
while (CCM->CDHIPR & CCM_CDHIPR_AHB_PODF_BUSY_MASK) spin(1);
|
|
||||||
SETBITS(CCM->CBCDR, CCM_CBCDR_IPG_PODF_MASK | CCM_CBCDR_AHB_PODF_MASK,
|
|
||||||
CCM_CBCDR_IPG_PODF(3)); // keep AHB, set IPG divider /4 (150MHz)
|
|
||||||
SETBITS(CCM->CSCMR1, CCM_CSCMR1_PERCLK_PODF_MASK,
|
|
||||||
CCM_CSCMR1_PERCLK_PODF(1)); // Set PERCLK divider /2 (75MHz)
|
|
||||||
// Set clock to 600 MHz. Power PLL on and configure divider (ROM boot code
|
|
||||||
// fiddles with the PLL, bypass first)
|
|
||||||
CCM_ANALOG->PLL_ARM |= CCM_ANALOG_PLL_ARM_BYPASS_MASK;
|
|
||||||
SETBITS(CCM_ANALOG->PLL_ARM,
|
|
||||||
CCM_ANALOG_PLL_ARM_POWERDOWN_MASK |
|
|
||||||
CCM_ANALOG_PLL_ARM_SET_DIV_SELECT_MASK,
|
|
||||||
CCM_ANALOG_PLL_ARM_SET_DIV_SELECT(100));
|
|
||||||
while ((CCM_ANALOG->PLL_ARM & CCM_ANALOG_PLL_ARM_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_ARM &=
|
|
||||||
~CCM_ANALOG_PLL_ARM_BYPASS_MASK; // Disable Bypass (switch to PLL)
|
|
||||||
// 14.5 Table 14-4: uart_clk_root
|
|
||||||
// 14.4: uart_clk_root = PLL3/6 or OSC; CCM_CSCDR1 (14.7.9) defaults to
|
|
||||||
// PLL3/6/1; but ROM boot code fiddles with the divider (9.5.3 Table 9-7)
|
|
||||||
CCM_ANALOG->PLL_USB1 |= CCM_ANALOG_PLL_USB1_POWER_MASK; // Power PLL on
|
|
||||||
while ((CCM_ANALOG->PLL_USB1 & CCM_ANALOG_PLL_USB1_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_USB1 &=
|
|
||||||
~CCM_ANALOG_PLL_USB1_BYPASS_MASK; // Disable Bypass (switch to PLL)
|
|
||||||
CCM->CSCDR1 &=
|
|
||||||
~(CCM_CSCDR1_UART_CLK_SEL_MASK | CCM_CSCDR1_UART_CLK_PODF_MASK);
|
|
||||||
rng_init(); // Initialise random number generator
|
|
||||||
// NXP startup code calls SystemInit BEFORE initializing RAM...
|
|
||||||
SysTick_Config(SYS_FREQUENCY / 1000); // Sys tick every 1ms
|
|
||||||
}
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
#define configUSE_PREEMPTION 1
|
|
||||||
#define configCPU_CLOCK_HZ SYS_FREQUENCY
|
|
||||||
#define configTICK_RATE_HZ 1000
|
|
||||||
#define configMAX_PRIORITIES 5
|
|
||||||
#define configUSE_16_BIT_TICKS 0
|
|
||||||
#define configUSE_TICK_HOOK 0
|
|
||||||
#define configUSE_IDLE_HOOK 0
|
|
||||||
#define configUSE_TIMERS 0
|
|
||||||
#define configUSE_CO_ROUTINES 0
|
|
||||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
|
||||||
#define configMINIMAL_STACK_SIZE 128
|
|
||||||
#define configTOTAL_HEAP_SIZE (1024 * 32)
|
|
||||||
#define INCLUDE_vTaskDelay 1
|
|
||||||
#define INCLUDE_xTaskGetSchedulerState 1 // trying
|
|
||||||
|
|
||||||
#ifdef __NVIC_PRIO_BITS
|
|
||||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
|
||||||
#else
|
|
||||||
#define configPRIO_BITS 4
|
|
||||||
#endif
|
|
||||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
|
|
||||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
|
|
||||||
#define configKERNEL_INTERRUPT_PRIORITY \
|
|
||||||
(configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
|
|
||||||
|
|
||||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
|
|
||||||
(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
|
|
||||||
|
|
||||||
#define configASSERT(expr) \
|
|
||||||
if (!(expr)) printf("FAILURE %s:%d: %s\n", __FILE__, __LINE__, #expr)
|
|
||||||
|
|
||||||
#define vPortSVCHandler SVC_Handler
|
|
||||||
#define xPortPendSVHandler PendSV_Handler
|
|
||||||
//#define xPortSysTickHandler SysTick_Handler
|
|
||||||
@@ -1,84 +1,29 @@
|
|||||||
CFLAGS = -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion
|
BOARD = rt1060
|
||||||
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
|
IDE = GCC+make
|
||||||
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
|
RTOS = FreeRTOS
|
||||||
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1062
|
WIZARD_URL ?= http://mongoose.ws/wizard
|
||||||
CFLAGS += -Icmsis_mcu/devices/MIMXRT1062/drivers -DCPU_MIMXRT1062DVL6B
|
|
||||||
CFLAGS += -mcpu=cortex-m7 -mthumb -mfloat-abi=hard -mfpu=fpv5-d16 $(CFLAGS_EXTRA)
|
|
||||||
LDSCRIPT = link.ld
|
|
||||||
LDFLAGS ?= -T$(LDSCRIPT) -nostdlib -nostartfiles --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
|
||||||
|
|
||||||
SOURCES = main.c syscalls.c sysinit.c
|
|
||||||
SOURCES += cmsis_mcu/devices/MIMXRT1062/gcc/startup_MIMXRT1062.S # NXP startup file. Compiler-dependent!
|
|
||||||
CFLAGS += -D__ATOLLIC__ -D__STARTUP_CLEAR_BSS # Make startup code work as expected
|
|
||||||
|
|
||||||
# FreeRTOS. RT1060 has a Cortex-M7 r1p2 core, FreeRTOS recommends using CM4F port for non-r0p1 CM7 micros
|
|
||||||
SOURCES += FreeRTOS-Kernel/portable/MemMang/heap_4.c
|
|
||||||
SOURCES += FreeRTOS-Kernel/portable/GCC/ARM_CM4F/port.c
|
|
||||||
CFLAGS += -IFreeRTOS-Kernel/include
|
|
||||||
CFLAGS += -IFreeRTOS-Kernel/portable/GCC/ARM_CM4F -Wno-conversion
|
|
||||||
|
|
||||||
# Mongoose options are defined in mongoose_config.h
|
|
||||||
SOURCES += mongoose.c net.c packed_fs.c
|
|
||||||
|
|
||||||
# Example specific build options. See README.md
|
|
||||||
CFLAGS += -DHTTP_URL=\"http://0.0.0.0/\"
|
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
|
||||||
RM = cmd /C del /Q /F /S
|
|
||||||
else
|
|
||||||
RM = rm -rf
|
|
||||||
endif
|
|
||||||
|
|
||||||
all build example update: SOURCES += flash_image.c
|
|
||||||
all build example: firmware.bin
|
all build example: firmware.bin
|
||||||
|
|
||||||
ram: LDSCRIPT = link_ram.ld
|
firmware.bin: wizard
|
||||||
ram: firmware.bin
|
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
|
||||||
|
|
||||||
firmware.bin: firmware.elf
|
wizard:
|
||||||
arm-none-eabi-objcopy -O binary $< $@
|
hash=$$(curl -s -X POST -H "Content-Type: application/json" -d '{"build":{"board":"$(BOARD)","ide":"$(IDE)","rtos":"$(RTOS)"}}' $(WIZARD_URL)/api/hash | jq -r '.hash') \
|
||||||
|
&& curl -s $(WIZARD_URL)/api/zip/$(BOARD)/$(IDE)/$(RTOS)/$$hash -o wizard.zip
|
||||||
|
unzip wizard.zip
|
||||||
|
cd wizard ; rm mongoose.[ch] ; ln -s ../../../../mongoose.c ; ln -s ../../../../mongoose.h
|
||||||
|
|
||||||
firmware.elf: FreeRTOS-Kernel cmsis_core cmsis_mcu $(SOURCES) hal.h link_ram.ld link.ld mongoose_config.h
|
|
||||||
arm-none-eabi-gcc $(SOURCES) $(wildcard FreeRTOS-Kernel/*.c) $(CFLAGS) $(LDFLAGS) -o $@
|
|
||||||
|
|
||||||
flash: firmware.bin
|
|
||||||
# flash
|
|
||||||
|
|
||||||
cmsis_core: # ARM CMSIS core headers
|
|
||||||
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
|
|
||||||
cmsis_mcu:
|
|
||||||
curl -sL https://mcuxpresso.nxp.com/cmsis_pack/repo/NXP.MIMXRT1062_DFP.17.1.0.pack -o $@.zip
|
|
||||||
mkdir $@ && cd $@ && unzip -q ../$@.zip
|
|
||||||
FreeRTOS-Kernel: # FreeRTOS sources
|
|
||||||
git clone --depth 1 -b V10.5.0 https://github.com/FreeRTOS/FreeRTOS-Kernel $@
|
|
||||||
|
|
||||||
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
# Automated remote test. Requires env variable VCON_API_KEY set. See https://vcon.io/automated-firmware-tests/
|
||||||
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/13
|
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/13
|
||||||
update: firmware.bin
|
update: firmware.bin
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
|
||||||
|
|
||||||
update updateram: CFLAGS += -DUART_DEBUG=LPUART3
|
test update: CFLAGS_EXTRA ="-DUART_DEBUG=LPUART3"
|
||||||
|
|
||||||
test: update
|
test: update
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=15 | tee /tmp/output.txt
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
||||||
|
|
||||||
|
|
||||||
updateram: ram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @firmware.bin
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0003 wm,e000edfc,1 wm,e000ed0c,5fa0004"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"init"}'
|
|
||||||
PC=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,4"}' | jq -r .resp[5:]` && \
|
|
||||||
SP=`curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"rm,0"}' | jq -r .resp[5:]` && \
|
|
||||||
REQ="wm,e000ed08,0 wr,d,$$SP wr,f,$$PC" && \
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"'"$$REQ"'"}'
|
|
||||||
curl -su :$(VCON_API_KEY) $(DEVICE_URL)/rpc/swd.exec -d '{"req":"wm,e000edf0,a05f0001"}'
|
|
||||||
|
|
||||||
testram: updateram
|
|
||||||
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/tx?t=5 | tee /tmp/output.txt
|
|
||||||
grep 'READY, IP:' /tmp/output.txt # Check for network init
|
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(RM) firmware.* *.su cmsis_core cmsis_mcu FreeRTOS-Kernel *.zip
|
rm -rf firmware.* wizard*
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
See [Wizard](https://mongoose.ws/wizard/#/output?board=rt1060&ide=GCC+make&rtos=FreeRTOS&file=README.md)
|
||||||
@@ -1 +0,0 @@
|
|||||||
../rt1060-evk-make-baremetal-builtin/dcd.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../rt1060-evk-make-baremetal-builtin/flash_image.c
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
// https://cache.nxp.com/secured/assets/documents/en/reference-manual/IMXRT1060XRM.pdf
|
|
||||||
// https://cache.nxp.com/secured/assets/documents/en/user-guide/MIMXRT1060EVKBUM.pdf
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "MIMXRT1062.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define BIT(x) (1UL << (x))
|
|
||||||
#define SETBITS(R, CLEARMASK, SETMASK) (R) = ((R) & ~(CLEARMASK)) | (SETMASK)
|
|
||||||
#define PIN(bank, num) ((((bank) - '0') << 8) | (num))
|
|
||||||
#define PINNO(pin) (pin & 255)
|
|
||||||
#define PINBANK(pin) (pin >> 8)
|
|
||||||
|
|
||||||
// Use LED for blinking, D8: GPIO_AD_B0_08. GPIO1.8 (schematics, RM)
|
|
||||||
#define LED PIN('1', 8)
|
|
||||||
|
|
||||||
#ifndef UART_DEBUG
|
|
||||||
#define UART_DEBUG LPUART1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// No settable constants, see sysinit.c
|
|
||||||
#define SYS_FREQUENCY 600000000UL
|
|
||||||
|
|
||||||
static inline void spin(volatile uint32_t count) {
|
|
||||||
while (count--) (void) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { CLOCK_OFF = 0U, CLOCK_ON_RUN = 1U, CLOCK_ON_RUN_WAIT = 3U };
|
|
||||||
static inline void clock_periph(uint32_t index, uint32_t shift, uint32_t val) {
|
|
||||||
volatile uint32_t *r = &CCM->CCGR0;
|
|
||||||
SETBITS(r[index], 3UL << shift, val << shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
// which peripheral feeds the pin
|
|
||||||
static inline void gpio_mux_config(uint16_t index, uint8_t af) {
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[index] = af;
|
|
||||||
}
|
|
||||||
|
|
||||||
// which pin feeds the peripheral (2nd stage)
|
|
||||||
static inline void periph_mux_config(uint16_t index, uint8_t in) {
|
|
||||||
IOMUXC->SELECT_INPUT[index] = in;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum { GPIO_MODE_INPUT, GPIO_MODE_OUTPUT };
|
|
||||||
enum { GPIO_OTYPE_PUSH_PULL, GPIO_OTYPE_OPEN_DRAIN };
|
|
||||||
enum { GPIO_SPEED_LOW, GPIO_SPEED_MEDIUM, GPIO_SPEED_MEDIUM_, GPIO_SPEED_HIGH };
|
|
||||||
enum { GPIO_PULL_NONE, GPIO_PULL_DOWN, GPIO_PULL_UP };
|
|
||||||
static inline GPIO_Type *gpio_bank(uint16_t pin) {
|
|
||||||
static const GPIO_Type *g[] = {NULL, GPIO1, GPIO2, GPIO3, NULL, GPIO5};
|
|
||||||
return (GPIO_Type *) g[PINBANK(pin)];
|
|
||||||
}
|
|
||||||
|
|
||||||
// pin driver/pull-up/down configuration (ignore "keeper")
|
|
||||||
static inline void gpio_pad_config(uint16_t index, uint8_t type, uint8_t speed,
|
|
||||||
uint8_t pull) {
|
|
||||||
bool dopull = pull > 0;
|
|
||||||
if (dopull) --pull;
|
|
||||||
IOMUXC->SW_PAD_CTL_PAD[index] =
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SPEED(speed) | IOMUXC_SW_PAD_CTL_PAD_ODE(type) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_SRE(speed >= GPIO_SPEED_HIGH) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUE(1) | IOMUXC_SW_PAD_CTL_PAD_PKE(dopull) |
|
|
||||||
IOMUXC_SW_PAD_CTL_PAD_PUS(pull) | IOMUXC_SW_PAD_CTL_PAD_DSE(7);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void gpio_init(uint16_t pin, uint8_t mode, uint8_t type,
|
|
||||||
uint8_t speed, uint8_t pull) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint8_t bit = (uint8_t) PINNO(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
switch (PINBANK(pin)) {
|
|
||||||
case 1:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(1, CCM_CCGR1_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00 + bit, 5);
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_00 + bit, type, speed,
|
|
||||||
pull);
|
|
||||||
clock_periph(0, CCM_CCGR0_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
gpio_mux_config(bit < 12 ? kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_00 + bit
|
|
||||||
: bit < 18
|
|
||||||
? kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 + bit - 12
|
|
||||||
: kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32 + bit - 18,
|
|
||||||
5);
|
|
||||||
gpio_pad_config(bit < 12 ? kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_00 + bit
|
|
||||||
: bit < 18
|
|
||||||
? kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_00 + bit - 12
|
|
||||||
: kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_32 + bit - 18,
|
|
||||||
type, speed, pull);
|
|
||||||
clock_periph(2, CCM_CCGR2_CG13_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
// TODO(): support sw_mux
|
|
||||||
clock_periph(1, CCM_CCGR1_CG15_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gpio->IMR &= ~mask;
|
|
||||||
if (mode == GPIO_MODE_INPUT) {
|
|
||||||
gpio->GDIR &= ~mask;
|
|
||||||
} else {
|
|
||||||
gpio->GDIR |= mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_input(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
static inline void gpio_output(uint16_t pin) {
|
|
||||||
gpio_init(pin, GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_NONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool gpio_read(uint16_t pin) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
return gpio->DR & mask;
|
|
||||||
}
|
|
||||||
static inline void gpio_write(uint16_t pin, bool value) {
|
|
||||||
GPIO_Type *gpio = gpio_bank(pin);
|
|
||||||
uint32_t mask = (uint32_t) BIT(PINNO(pin));
|
|
||||||
if (value) {
|
|
||||||
gpio->DR |= mask;
|
|
||||||
} else {
|
|
||||||
gpio->DR &= ~mask;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static inline void gpio_toggle(uint16_t pin) {
|
|
||||||
gpio_write(pin, !gpio_read(pin));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 14.5 Table 14-4: uart_clk_root
|
|
||||||
// see sysinit.c for clocks, (14.7.9: defaults to pll3_80m = PLL3/6/1 = 80MHz)
|
|
||||||
static inline void uart_init(LPUART_Type *uart, unsigned long baud) {
|
|
||||||
uint8_t af = 2; // Alternate function
|
|
||||||
uint16_t mr = 0, pr = 0, mt = 0, pt = 0; // pins
|
|
||||||
uint32_t freq = 80000000; // uart_clk_root frequency
|
|
||||||
if (uart == LPUART1)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_12,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B0_13;
|
|
||||||
if (uart == LPUART3)
|
|
||||||
mt = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06,
|
|
||||||
pt = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_06,
|
|
||||||
mr = kIOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07,
|
|
||||||
pr = kIOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07;
|
|
||||||
|
|
||||||
if (uart == LPUART1) clock_periph(5, CCM_CCGR5_CG12_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
if (uart == LPUART3) clock_periph(0, CCM_CCGR0_CG6_SHIFT, CLOCK_ON_RUN_WAIT);
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(mt, af);
|
|
||||||
gpio_pad_config(pt, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(mr, af);
|
|
||||||
gpio_pad_config(pr, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
uart->GLOBAL |= LPUART_GLOBAL_RST_MASK; // reset, CTRL = 0, defaults
|
|
||||||
uart->GLOBAL &= ~LPUART_GLOBAL_RST_MASK;
|
|
||||||
SETBITS(uart->BAUD,
|
|
||||||
LPUART_BAUD_OSR_MASK | LPUART_BAUD_SBR_MASK | LPUART_BAUD_SBNS_MASK,
|
|
||||||
LPUART_BAUD_OSR(16 - 1) |
|
|
||||||
LPUART_BAUD_SBR(freq / (16 * baud))); // Rx sample at 16x
|
|
||||||
SETBITS(uart->CTRL,
|
|
||||||
LPUART_CTRL_PE_MASK | LPUART_CTRL_M_MASK | LPUART_CTRL_ILT_MASK |
|
|
||||||
LPUART_CTRL_IDLECFG_MASK,
|
|
||||||
LPUART_CTRL_IDLECFG(1) | LPUART_CTRL_ILT(1) |
|
|
||||||
LPUART_BAUD_SBNS(0)); // no parity, idle 2 chars after 1 stop bit
|
|
||||||
uart->CTRL |= LPUART_CTRL_TE_MASK | LPUART_CTRL_RE_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void uart_write_byte(LPUART_Type *uart, uint8_t byte) {
|
|
||||||
uart->DATA = byte;
|
|
||||||
while ((uart->STAT & LPUART_STAT_TDRE_MASK) == 0) spin(1);
|
|
||||||
}
|
|
||||||
static inline void uart_write_buf(LPUART_Type *uart, char *buf, size_t len) {
|
|
||||||
while (len-- > 0) uart_write_byte(uart, *(uint8_t *) buf++);
|
|
||||||
}
|
|
||||||
static inline int uart_read_ready(LPUART_Type *uart) {
|
|
||||||
(void) uart;
|
|
||||||
return uart->STAT & LPUART_STAT_RDRF_MASK;
|
|
||||||
}
|
|
||||||
static inline uint8_t uart_read_byte(LPUART_Type *uart) {
|
|
||||||
return (uint8_t) (uart->DATA & 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void rng_init(void) {
|
|
||||||
clock_periph(6, CCM_CCGR6_CG6_SHIFT, CLOCK_ON_RUN_WAIT); // trng_clk
|
|
||||||
SETBITS(TRNG->MCTL,
|
|
||||||
TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK | TRNG_MCTL_RST_DEF_MASK,
|
|
||||||
TRNG_MCTL_PRGM(1) | TRNG_MCTL_ERR(1) |
|
|
||||||
TRNG_MCTL_RST_DEF(1)); // reset to default values
|
|
||||||
SETBITS(TRNG->MCTL, TRNG_MCTL_PRGM_MASK | TRNG_MCTL_ERR_MASK,
|
|
||||||
TRNG_MCTL_PRGM(0)); // set to run mode
|
|
||||||
(void) TRNG->ENT[TRNG_ENT_COUNT - 1]; // start new entropy generation
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
}
|
|
||||||
static inline uint32_t rng_read(void) {
|
|
||||||
static uint8_t idx = 0;
|
|
||||||
while ((TRNG->MCTL & TRNG_MCTL_ENT_VAL_MASK) == 0) (void) 0;
|
|
||||||
uint32_t data = TRNG->ENT[idx++]; // read data
|
|
||||||
idx %= TRNG_ENT_COUNT; // stay within array limits
|
|
||||||
if (idx == 0) // we've just read TRNG_ENT_COUNT - 1
|
|
||||||
(void) TRNG->ENT[0]; // defect workaround
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - PHY has no xtal, XI driven from ENET_REF_CLK1 (labeled as ENET_TX_REF_CLK
|
|
||||||
// (GPIO_AD_B1_10)), generated by the MCU
|
|
||||||
// - PHY RST connected to GPIO1.9 (GPIO_AD_B0_09); INTRP/NAND_TREE connected to
|
|
||||||
// GPIO1.10 (GPIO_AD_B0_10)
|
|
||||||
// - 41.4 REF_CLK1 is RMII mode reference clock for Rx, Tx, and SMI; it is I/O
|
|
||||||
// - 11.3.2 IOMUXC_GPR_GPR1
|
|
||||||
// - bit 13: ENET1_CLK_SEL --> 0 ENET1 TX reference clock driven by
|
|
||||||
// ref_enetpll and output via ENET_REF_CLK1 (labeled as ENET_REF_CLK
|
|
||||||
// elsewhere)
|
|
||||||
// - bit 17: ENET1_TX_CLK_DIR --> 1 ENET1_TX_CLK output driver enabled
|
|
||||||
// - 14.6.1.3.6 Ethernet PLL (PLL6)
|
|
||||||
// - 14.8.14: configure PLL6 to generate 50MHz clocks for ENET and RMII.
|
|
||||||
static inline void ethernet_init(void) {
|
|
||||||
// setup PLL and clock ENET from it
|
|
||||||
SETBITS(CCM_ANALOG->PLL_ENET, CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_MASK |
|
|
||||||
CCM_ANALOG_PLL_ENET_BYPASS_CLK_SRC(0)); // bypass to 24MHz osc
|
|
||||||
SETBITS(
|
|
||||||
CCM_ANALOG->PLL_ENET,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT_MASK | CCM_ANALOG_PLL_ENET_POWERDOWN_MASK,
|
|
||||||
CCM_ANALOG_PLL_ENET_DIV_SELECT(1) | CCM_ANALOG_PLL_ENET_ENABLE_MASK);
|
|
||||||
while ((CCM_ANALOG->PLL_ENET & CCM_ANALOG_PLL_ENET_LOCK_MASK) == 0)
|
|
||||||
spin(1); // wait until it is stable
|
|
||||||
CCM_ANALOG->PLL_ENET &= ~CCM_ANALOG_PLL_ENET_BYPASS_MASK;
|
|
||||||
|
|
||||||
gpio_init(PIN('1', 9), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP); // set GPIO1.9 as GPIO (PHY \RST)
|
|
||||||
gpio_write(PIN('1', 9), 0); // reset PHY
|
|
||||||
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_10,
|
|
||||||
6); // set for ENET_REF_CLK
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_10] |=
|
|
||||||
IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_ENET_IPG_CLK_RMII_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_10, so RMII clock is taken
|
|
||||||
// from ENET_REF_CLK
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_10, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
IOMUXC_GPR->GPR1 |=
|
|
||||||
IOMUXC_GPR_GPR1_ENET1_TX_CLK_DIR(1); // Set ENET_TX_CLK as output
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_04, 3); // set for RXDATA0
|
|
||||||
periph_mux_config(kIOMUXC_ENET0_RXDATA_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_04
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_04, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_05, 3); // set for RXDATA1
|
|
||||||
periph_mux_config(kIOMUXC_ENET1_RXDATA_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_05
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_05, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_06, 3); // set for CRS
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RXEN_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B1_06
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_06, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_07, 3); // set for TXDATA0
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_07, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_08, 3); // set for TXDATA1
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_08, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_09, 3); // set for TXEN
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_09, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_B1_11, 3); // set for RXERR
|
|
||||||
periph_mux_config(kIOMUXC_ENET_RXERR_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from B0_12
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_B1_11, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_HIGH, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_40, 4); // set for MDC
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_40, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_41, 4); // set for MDIO
|
|
||||||
periph_mux_config(kIOMUXC_ENET_MDIO_SELECT_INPUT,
|
|
||||||
1); // drive peripheral from EMC_41
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_EMC_41, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM, GPIO_PULL_UP);
|
|
||||||
|
|
||||||
gpio_init(PIN('1', 10), GPIO_MODE_OUTPUT, GPIO_OTYPE_PUSH_PULL,
|
|
||||||
GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // set GPIO1.10 as GPIO (PHY INTRP/NAND_TREE)
|
|
||||||
gpio_write(PIN('1', 10), 1); // prevent NAND_TREE
|
|
||||||
spin(10000); // keep PHY RST low for a while
|
|
||||||
gpio_write(PIN('1', 9), 1); // deassert RST
|
|
||||||
gpio_init(PIN('1', 10), GPIO_MODE_INPUT, 0, GPIO_SPEED_MEDIUM,
|
|
||||||
GPIO_PULL_UP); // setup IRQ (pulled-up)(not used)
|
|
||||||
|
|
||||||
clock_periph(1, CCM_CCGR1_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enet_ipg_clk
|
|
||||||
NVIC_EnableIRQ(ENET_IRQn); // Setup Ethernet IRQ handler
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper macro for MAC generation, byte reads not allowed
|
|
||||||
#define GENERATE_LOCALLY_ADMINISTERED_MAC() \
|
|
||||||
{ \
|
|
||||||
2, OCOTP->CFG0 & 255, (OCOTP->CFG0 >> 10) & 255, \
|
|
||||||
((OCOTP->CFG0 >> 19) ^ (OCOTP->CFG1 >> 19)) & 255, \
|
|
||||||
(OCOTP->CFG1 >> 10) & 255, OCOTP->CFG1 & 255 \
|
|
||||||
}
|
|
||||||
// NOTE: You can fuse your own MAC and read it from OCOTP->MAC0, OCOTP->MAC1,
|
|
||||||
// OCOTP->MAC2
|
|
||||||
|
|
||||||
static inline void flash_init(void) { // QSPI in FlexSPI
|
|
||||||
// set pins
|
|
||||||
clock_periph(4, CCM_CCGR4_CG1_SHIFT, CLOCK_ON_RUN_WAIT); // iomuxc_ipg_clk_s
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05, 1); // set for DQS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_05] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DQS_SELECT_INPUT, 0); // drive peripheral from B1_05
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_05, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06, 1); // set for SS
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_06] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_06, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07, 1); // set for SCLK
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_07] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_SCK_SELECT_INPUT, 0); // drive peripheral from B1_07
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_07, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08, 1); // set for DATA0
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_08] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA0_SELECT_INPUT, 0); // drive peripheral from B1_08
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_08, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09, 1); // set for DATA1
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_09] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA1_SELECT_INPUT, 0); // drive peripheral from B1_09
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_09, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10, 1); // set for DATA2
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_10] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA2_SELECT_INPUT, 0); // drive peripheral from B1_10
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_10, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
gpio_mux_config(kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11, 1); // set for DATA3
|
|
||||||
IOMUXC->SW_MUX_CTL_PAD[kIOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B1_11] |= IOMUXC_SW_MUX_CTL_PAD_SION(1); // loop signal back from pin
|
|
||||||
periph_mux_config(kIOMUXC_FLEXSPIA_DATA3_SELECT_INPUT, 0); // drive peripheral from B1_11
|
|
||||||
gpio_pad_config(kIOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B1_11, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, GPIO_PULL_NONE);
|
|
||||||
// set FlexSPI clock
|
|
||||||
SETBITS(CCM->CSCMR1, CCM_CSCMR1_FLEXSPI_CLK_SEL_MASK | CCM_CSCMR1_FLEXSPI_PODF_MASK, CCM_CSCMR1_FLEXSPI_CLK_SEL(3) | CCM_CSCMR1_FLEXSPI_PODF(7)); // select PLL3 PFD0 /8
|
|
||||||
clock_periph(6, CCM_CCGR6_CG5_SHIFT, CLOCK_ON_RUN_WAIT); // enable
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
ENTRY(Reset_Handler);
|
|
||||||
MEMORY {
|
|
||||||
flash_hdr(rx) : ORIGIN = 0x60000000, LENGTH = 8k
|
|
||||||
flash_irq(rx) : ORIGIN = 0x60002000, LENGTH = 1k
|
|
||||||
flash_code(rx) : ORIGIN = 0x60002400, LENGTH = 8183k
|
|
||||||
|
|
||||||
itcram(rx) : ORIGIN = 0x00000000, LENGTH = 128k
|
|
||||||
dtcram(rw) : ORIGIN = 0x20000000, LENGTH = 128k
|
|
||||||
ocram(rw) : ORIGIN = 0x20200000, LENGTH = 256k /* Is this cached ? */
|
|
||||||
}
|
|
||||||
__StackTop = ORIGIN(dtcram) + LENGTH(dtcram);
|
|
||||||
|
|
||||||
SECTIONS {
|
|
||||||
.hdr : { FILL(0xff) ; KEEP(*(.cfg)) . = 0x1000 ; KEEP(*(.ivt)) . = 0x1020 ;
|
|
||||||
KEEP(*(.dat)) . = 0x1030 ; KEEP(*(.dcd)) . = 0x2000 ;} >flash_hdr
|
|
||||||
.irq : { KEEP(*(.isr_vector)) } > flash_irq
|
|
||||||
.text : { *(.text* .text.*) *(.rodata*) ; } > flash_code
|
|
||||||
.data : { __data_start__ = .; *(.data SORT(.data.*)) __data_end__ = .; } > dtcram AT > flash_code
|
|
||||||
__etext = LOADADDR(.data);
|
|
||||||
.bss : { __bss_start__ = .; *(.bss SORT(.bss.*) COMMON) __bss_end__ = .; } > dtcram
|
|
||||||
_end = .;
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
// Copyright (c) 2023 Cesanta Software Limited
|
|
||||||
// All rights reserved
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
#include "mongoose.h"
|
|
||||||
#include "net.h"
|
|
||||||
|
|
||||||
#define BLINK_PERIOD_MS 1000 // LED blinking period in millis
|
|
||||||
|
|
||||||
// workaround optimizer somehow causing SysTick to fire before FreeRTOS has
|
|
||||||
// fully initialized
|
|
||||||
extern void xPortSysTickHandler(void);
|
|
||||||
void SysTick_Handler(void) {
|
|
||||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
|
|
||||||
xPortSysTickHandler();
|
|
||||||
}
|
|
||||||
|
|
||||||
void mg_random(void *buf, size_t len) { // Use on-board RNG
|
|
||||||
for (size_t n = 0; n < len; n += sizeof(uint32_t)) {
|
|
||||||
uint32_t r = rng_read();
|
|
||||||
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void timer_fn(void *arg) {
|
|
||||||
struct mg_tcpip_if *ifp = arg; // And show
|
|
||||||
const char *names[] = {"down", "up", "req", "ready"}; // network stats
|
|
||||||
MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
|
||||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
|
||||||
ifp->ndrop, ifp->nerr));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void server(void *args) {
|
|
||||||
struct mg_mgr mgr; // Initialise Mongoose event manager
|
|
||||||
mg_mgr_init(&mgr); // and attach it to the interface
|
|
||||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
|
||||||
|
|
||||||
// Initialise Mongoose network stack
|
|
||||||
ethernet_init();
|
|
||||||
struct mg_tcpip_driver_imxrt_data driver_data = {.mdc_cr = 24, .phy_addr = 2};
|
|
||||||
struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC(),
|
|
||||||
// Uncomment below for static configuration:
|
|
||||||
// .ip = mg_htonl(MG_U32(192, 168, 0, 223)),
|
|
||||||
// .mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
|
||||||
// .gw = mg_htonl(MG_U32(192, 168, 0, 1)),
|
|
||||||
.driver = &mg_tcpip_driver_imxrt,
|
|
||||||
.driver_data = &driver_data};
|
|
||||||
mg_tcpip_init(&mgr, &mif);
|
|
||||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif);
|
|
||||||
|
|
||||||
MG_INFO(("MAC: %M. Waiting for IP...", mg_print_mac, mif.mac));
|
|
||||||
while (mif.state != MG_TCPIP_STATE_READY) {
|
|
||||||
mg_mgr_poll(&mgr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
MG_INFO(("Initialising application..."));
|
|
||||||
web_init(&mgr);
|
|
||||||
|
|
||||||
MG_INFO(("Starting event loop"));
|
|
||||||
for (;;) mg_mgr_poll(&mgr, 1); // Infinite event loop
|
|
||||||
(void) args;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void blinker(void *args) {
|
|
||||||
gpio_output(LED); // Setup blue LED
|
|
||||||
for (;;) {
|
|
||||||
gpio_toggle(LED);
|
|
||||||
vTaskDelay(pdMS_TO_TICKS(BLINK_PERIOD_MS));
|
|
||||||
}
|
|
||||||
(void) args;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
uart_init(UART_DEBUG, 115200); // Initialise UART
|
|
||||||
|
|
||||||
// Start tasks. NOTE: stack sizes are in 32-bit words
|
|
||||||
xTaskCreate(blinker, "blinker", 128, ":)", configMAX_PRIORITIES - 1, NULL);
|
|
||||||
xTaskCreate(server, "server", 2048, 0, configMAX_PRIORITIES - 1, NULL);
|
|
||||||
|
|
||||||
vTaskStartScheduler(); // This blocks
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <errno.h> // we are not using lwIP
|
|
||||||
|
|
||||||
// See https://mongoose.ws/documentation/#build-options
|
|
||||||
#define MG_ARCH MG_ARCH_FREERTOS
|
|
||||||
|
|
||||||
#define MG_ENABLE_TCPIP 1
|
|
||||||
#define MG_ENABLE_DRIVER_IMXRT 1
|
|
||||||
#define MG_IO_SIZE 256
|
|
||||||
#define MG_ENABLE_CUSTOM_RANDOM 1
|
|
||||||
#define MG_ENABLE_PACKED_FS 1
|
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../device-dashboard/net.c
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../device-dashboard/net.h
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../device-dashboard/packed_fs.c
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "hal.h"
|
|
||||||
|
|
||||||
int _fstat(int fd, struct stat *st) {
|
|
||||||
if (fd < 0) return -1;
|
|
||||||
st->st_mode = S_IFCHR;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *_sbrk(int incr) {
|
|
||||||
extern char _end;
|
|
||||||
static unsigned char *heap = NULL;
|
|
||||||
unsigned char *prev_heap;
|
|
||||||
if (heap == NULL) heap = (unsigned char *) &_end;
|
|
||||||
prev_heap = heap;
|
|
||||||
heap += incr;
|
|
||||||
return prev_heap;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _open(const char *path) {
|
|
||||||
(void) path;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _close(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _isatty(int fd) {
|
|
||||||
(void) fd;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _lseek(int fd, int ptr, int dir) {
|
|
||||||
(void) fd, (void) ptr, (void) dir;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _exit(int status) {
|
|
||||||
(void) status;
|
|
||||||
for (;;) asm volatile("BKPT #0");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _kill(int pid, int sig) {
|
|
||||||
(void) pid, (void) sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _getpid(void) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _write(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
if (fd == 1) uart_write_buf(UART_DEBUG, ptr, (size_t) len);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _read(int fd, char *ptr, int len) {
|
|
||||||
(void) fd, (void) ptr, (void) len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _link(const char *a, const char *b) {
|
|
||||||
(void) a, (void) b;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _unlink(const char *a) {
|
|
||||||
(void) a;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int _stat(const char *path, struct stat *st) {
|
|
||||||
(void) path, (void) st;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mkdir(const char *path, mode_t mode) {
|
|
||||||
(void) path, (void) mode;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _init(void) {}
|
|
||||||
Loaded 100 of 1366 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user