Compare commits

..
329 Commits
Author SHA1 Message Date
Sergio R. Caprile 0a86bc0af2 update version 2025-02-19 10:21:27 -03:00
Sergio R. Caprile bc9f6ba0b0 Merge pull request #3043 from cesanta/loserst
add TLS support
2025-02-18 16:22:48 -03:00
Sergio R. Caprile 9e16a0ae42 add TLS support 2025-02-18 16:20:39 -03:00
Sergio R. Caprile 9ccbb49aef Merge pull request #3042 from cesanta/loserst
Fix Windows returning IO_RESET
2025-02-18 16:08:24 -03:00
Sergio R. Caprile d59f84fbbc Fix Windows returning IO_RESET 2025-02-18 16:04:13 -03:00
Sergio R. Caprile 4bbb5008b1 Merge pull request #3039 from cesanta/rw612-eth-driver
RW612 ETH driver
2025-02-18 09:28:16 -03:00
Sergio R. Caprile 49ce25511e Merge pull request #3041 from cesanta/atomillis
no LDRD in v6-M
2025-02-17 13:59:14 -03:00
Sergio R. Caprile 985276665d no LDRD in v6-M 2025-02-17 10:18:51 -03:00
robert 91f553c45f RW612 ETH driver 2025-02-17 03:47:41 -05:00
Sergey Lyubka 38ede8ec58 2024 -> 2025 2025-02-12 13:28:24 +00:00
Sergey Lyubka 997f6543ce Merge pull request #3037 from cesanta/tls2
TLS verification
2025-02-10 15:42:18 +00:00
Sergey Lyubka b50081a83b TLS verification 2025-02-10 15:36:29 +00:00
Sergio R. Caprile 34f512d244 Merge pull request #3034 from cesanta/picosdk
Fix Pico-SDK aggressive optimization breaking OTA
2025-02-06 10:31:09 -03:00
Sergio R. Caprile eb5752f41b Fix Pico-SDK aggressive optimization breaking OTA 2025-02-06 10:27:13 -03:00
Sergio R. Caprile ef8e7419fa ... 2025-02-02 19:41:54 -03:00
Sergio R. Caprile cfcdd15b89 ... 2025-02-02 19:28:54 -03:00
Sergio R. Caprile b26debaebc ... 2025-02-02 19:25:35 -03:00
Sergio R. Caprile 6deb061b12 ... 2025-02-02 19:20:30 -03:00
novlean 4c6745670c Merge pull request #3029 from cesanta/novlean-patch-1
Update LICENSE
2025-01-30 12:10:39 +00:00
novlean 01c662b7de Update LICENSE
2025
2025-01-30 12:10:26 +00:00
Sergio R. Caprile 179fe652c2 Merge pull request #3028 from cesanta/ota2350
Use BootROM reset for RP2350
2025-01-29 15:20:37 -03:00
Sergio R. Caprile 394bc3260d Use BootROM reset for RP2350 2025-01-29 15:17:04 -03:00
Sergio R. Caprile ce1a70e2dc fix error msg 2025-01-29 10:15:45 -03:00
Sergio R. Caprile 99022896f6 Merge pull request #3026 from cesanta/tst
misc fixes
2025-01-28 15:29:43 -03:00
Sergio R. Caprile 446b400667 misc fixes 2025-01-28 15:27:13 -03:00
Sergio R. Caprile 7d53c21efe fix for no TLS 2025-01-27 18:52:20 -03:00
Sergio R. Caprile b78efbac36 Merge pull request #3024 from cesanta/test
fix failing tests
2025-01-27 16:52:06 -03:00
Sergio R. Caprile 9be9dcec46 misc 2025-01-27 16:50:46 -03:00
Sergio R. Caprile 3766ab802b update SDK (no pico_rand) 2025-01-27 16:49:32 -03:00
Sergio R. Caprile b9141925a3 fix #2997 2025-01-27 16:15:03 -03:00
Sergio R. Caprile ed79fe86aa fix SDK 1.5 not building in recent gcc (update to SDK 2.1) 2025-01-27 14:26:11 -03:00
Sergey Lyubka 2f0b0955a9 Merge pull request #3023 from cesanta/smtp
fix built-in TLS not calling MG_EV_TLS_HS; uniformize mg_tls_init()
2025-01-27 14:44:51 +00:00
Sergio R. Caprile 2f8e15a900 fix qemu package name 2025-01-27 11:13:38 -03:00
Sergio R. Caprile b8b3a5c305 fix built-in TLS not calling MG_EV_TLS_HS; uniformize mg_tls_init() 2025-01-27 10:54:56 -03:00
Sergio R. Caprile e7ea421c54 fix outdated mongoose.h 2025-01-27 10:54:29 -03:00
Sergio R. Caprile 8de9699390 fix TLS multiple-record-per-frame handling in bare metal 2025-01-24 12:05:17 -03:00
Sergio R. Caprile bf592a22ae Fix TLS tests failing with small(lots of) records 2025-01-23 19:15:40 -03:00
Sergio R. Caprile 8d4a619a15 minimize elusive ARP lookup failure 2025-01-23 14:33:28 -03:00
Sergio R. Caprile 1a3588624d update mongoose.h 2025-01-21 16:50:14 -03:00
Sergio R. Caprile 74b3fd2efc Merge pull request #3009 from cesanta/fin
Close connection fast if both sides sent FIN
2025-01-17 20:07:35 -03:00
Sergio R. Caprile 091356ed59 give TLS a chance 2025-01-17 19:51:12 -03:00
Sergey Lyubka fc0e1ee311 Close connection fast if both sides sent FIN 2025-01-17 15:15:24 -03:00
Sergio R. Caprile 8dbfcbff58 Merge pull request #3014 from cesanta/test
improve TLS testing
2025-01-17 15:14:04 -03:00
Sergio R. Caprile 317591bc8a improve TLS testing 2025-01-17 14:07:49 -03:00
Sergio R. Caprile f71b3b91c0 Rollback 2025-01-16 21:04:12 -03:00
Sergio R. Caprile 9e255bcbce fix undefined behaviour 2025-01-16 20:42:43 -03:00
Sergio R. Caprile 8af319b953 Merge pull request #3011 from cesanta/to512
Change default MG_IO_SIZE 256 -> 512
2025-01-15 16:13:15 -03:00
Sergey Lyubka f90fd9cec4 Change default MG_IO_SIZE 256 -> 512 2025-01-15 19:10:10 +00:00
robert d386b1c12d XMC4 driver: added IDE compatibility 2025-01-13 03:34:25 -05:00
Sergey Lyubka 81551ec50d Quiet clone 2025-01-06 17:47:50 +00:00
Sergio R. Caprile 8fafcf6eaa Merge pull request #3001 from cesanta/towizard
move to Wizard
2025-01-03 11:54:36 -03:00
Sergio R. Caprile f0df6c61c9 move to Wizard 2025-01-03 11:53:11 -03:00
Sergey Lyubka 6cf36b5771 Add esp32-mqtt 2024-12-30 22:58:33 +00:00
Sergio R. Caprile 54799187e9 Merge pull request #2996 from cesanta/test
improve tests and debuggability
2024-12-30 13:41:02 -03:00
Sergio R. Caprile 6d0320be06 improve tests and debuggability 2024-12-30 12:25:27 -03:00
Sergey Lyubka 317a1527ad Add HTTPS 2024-12-29 14:03:39 +00:00
Sergey Lyubka 490eb0f57f Squash warning 2024-12-29 11:29:09 +00:00
Sergio R. Caprile f95283e341 Merge pull request #2995 from cesanta/update
misc fixes and updates
2024-12-27 11:21:50 -03:00
Sergio R. Caprile 837da0e458 misc fixes and updates 2024-12-27 11:16:10 -03:00
Sergio R. Caprile 8ce82a100e Merge pull request #2972 from cesanta/imxrt
move to Wizard
2024-12-27 09:17:43 -03:00
Sergio R. Caprile 9ece98c101 Merge pull request #2994 from cesanta/pico2w
Add Pico 2 W examples
2024-12-23 15:19:30 -03:00
Sergio R. Caprile 6a83147b33 Add Pico 2 W examples 2024-12-23 15:11:29 -03:00
Sergio R. Caprile 90e4228e1d keep TLS options as per the TLS tutorial. Default to built-in TLS while allowing to use other stacks, as tutorials show 2024-12-23 11:40:36 -03:00
Sergey Lyubka 553aeeef77 Add TLS support 2024-12-20 06:47:31 +00:00
Sergey Lyubka 6147e865f8 Update README 2024-12-19 12:38:20 +00:00
Sergey Lyubka 7b296fabb0 Merge pull request #2991 from cesanta/unpacked_crash
Fix mg_unpacked() crash
2024-12-18 11:07:27 +00:00
Sergey Lyubka 00c8f8acd0 Fix mg_unpacked() crash 2024-12-18 09:57:18 +00:00
Sergey Lyubka 1e1efa2c5e Merge pull request #2988 from cesanta/tlspoll
fix mg_tls_pending
2024-12-17 14:24:13 +00:00
robertc2000 b0b0dd9f0b Merge pull request #2990 from cesanta/w5100
Add W5100 driver
2024-12-17 15:34:54 +02:00
robert 30bb1c52d0 Add W5100 driver 2024-12-17 06:35:21 -05:00
Sergio R. Caprile 7fc96a61ad fix mg_tls_pending 2024-12-16 16:03:36 -03:00
Sergio R. Caprile 4a164c39b4 Merge pull request #2987 from cesanta/ifp
mgr::priv -> mgr::ifp, use explicit type
2024-12-16 11:36:36 -03:00
Sergey Lyubka b0e4069bb7 mgr::priv -> mgr::ifp, use explicit type 2024-12-16 14:22:13 +00:00
Sergey Lyubka 19cbb27b4c Fix TLS handling in net_builtin 2024-12-15 13:32:19 +00:00
Sergey Lyubka d44c864387 Add arduino/esp32-http example 2024-12-10 15:27:09 +00:00
Sergio R. Caprile 36e21e53e0 Merge pull request #2982 from cesanta/picowsdk
Add auto init for Pico-W driver
2024-12-05 14:59:21 -03:00
Sergio R. Caprile b7598cc354 Add auto init for Pico-W driver 2024-12-05 14:57:21 -03:00
Sergio R. Caprile 0a4f322d49 Merge pull request #2981 from cesanta/picowsdk
Add Pico-W driver in src/drivers
2024-12-05 12:21:41 -03:00
Sergio R. Caprile bf013fcdae Add Pico-W driver in src/drivedrivers 2024-12-05 12:11:14 -03:00
Sergey Lyubka fd52fccc15 Merge pull request #2976 from cesanta/http-invalid-versions
Validate HTTP version
2024-12-04 14:04:39 +00:00
robert c493d3a4ce Validate HTTP version 2024-12-04 06:34:24 -05:00
Sergio R. Caprile aeceb2b9e7 Merge pull request #2979 from cesanta/sdk2
update to Pico-SDK 2.0.0
2024-12-03 17:10:01 -03:00
Sergio R. Caprile cb5f833dd2 update to Pico-SDK 2.0.0 2024-12-02 14:19:49 -03:00
Sergio R. Caprile 0740ccd9f7 Merge pull request #2978 from cesanta/sdk2
update to Pico-SDK 2.0.0
2024-12-02 11:19:14 -03:00
Sergio R. Caprile 716c84c896 update to Pico-SDK 2.0.0 2024-12-02 11:15:33 -03:00
Sergey Lyubka c5fda07d1e Update Arduino sketches 2024-12-01 22:04:57 +00:00
Sergey Lyubka 7fffe0abaa Add simple RAM profiler 2024-11-28 13:11:04 +00:00
Sergey Lyubka 8a42325c23 Back to plain MQTT URL 2024-11-28 08:50:32 +00:00
Sergey Lyubka 78900304bf More PPP nitpicks 2024-11-28 08:46:32 +00:00
Sergey Lyubka fb6dfbcd3c PPP nitpicks 2024-11-28 08:31:43 +00:00
Sergey Lyubka 3dd4c7da2a Add PPP driver 2024-11-27 22:00:30 +00:00
Sergey Lyubka 03c955410c Update HTTP server Arduino example 2024-11-26 20:53:21 +00:00
Sergio R. Caprile 74f77c9ded Merge pull request #2975 from cesanta/ipsum
Fix IP csum calculation on 8-bit platforms
2024-11-26 17:36:43 -03:00
Sergey Lyubka 3caca03e8a Simplify MQTT example 2024-11-26 20:30:57 +00:00
Sergey Lyubka 49469840ab Fix IP csum calculation on 8-bit platforms 2024-11-26 20:23:12 +00:00
Sergio R. Caprile 85613ab02d Merge pull request #2974 from cesanta/noclash
avoid name clashing in OTA
2024-11-26 14:18:58 -03:00
Sergio R. Caprile 6e4ce85c87 avoid name clashing in OTA 2024-11-26 14:15:56 -03:00
Sergio R. Caprile 2a093dc183 remove is_io_err (unused) 2024-11-26 14:09:34 -03:00
Sergey Lyubka 01eeadbaf4 Merge pull request #2970 from kursataktas/mongoose-guru
Introducing Mongoose Guru on Gurubase.io
2024-11-23 08:22:57 +00:00
Sergio R. Caprile 851b3a7cfb move to Wizard 2024-11-22 17:38:26 -03:00
Sergio R. Caprile b6dc830bcb Merge pull request #2964 from cesanta/http-cookie
Use separate cookies for HTTP and HTTPS connections
2024-11-22 16:39:08 -03:00
Sergio R. Caprile 8ef02aae41 Merge pull request #2971 from cesanta/411
Fix issuing 411 responses as a client
2024-11-22 16:37:19 -03:00
Sergio R. Caprile 423dbd58a1 Merge pull request #2929 from cesanta/xmc7200
move to Wizard
2024-11-22 16:36:12 -03:00
Sergio R. Caprile 5582db615a Merge pull request #2923 from cesanta/1170
move to Wizard
2024-11-22 14:05:59 -03:00
Sergio R. Caprile 1479ebfb5d move to Wizard 2024-11-22 14:01:32 -03:00
Sergio R. Caprile 4389ef1e77 Merge pull request #2927 from cesanta/mcxn
move to Wizard
2024-11-22 12:21:36 -03:00
Sergio R. Caprile 5c305e7fa8 Fix issuing 411 responses as a client
15.5.12. 411 Length Required

The 411 (Length Required) status code indicates that the server refuses to accept the request without a defined Content-Length (Section 8.6). The client MAY repeat the request if it adds a valid Content-Length header field containing the length of the request content.

fixes #2969
2024-11-21 18:55:16 -03:00
Kursat Aktas 0427908eae Introducing Mongoose Guru on Gurubase.io
Signed-off-by: Kursat Aktas <kursat.ce@gmail.com>
2024-11-21 19:23:44 +03:00
Sergio R. Caprile 2df53c3d27 update version 2024-11-20 10:02:24 -03:00
Sergio R. Caprile 53ec9adb1b Merge pull request #2954 from cesanta/dbl
Fix dbl printing
2024-11-19 16:20:30 -03:00
Sergio R. Caprile 8b95a22e75 Merge pull request #2966 from cesanta/ota-h7-dual-core
H7 dual core OTA fix
2024-11-14 14:23:17 -03:00
robert 665298a04b H7 dual core OTA compatibility 2024-11-14 10:22:36 -05:00
Sergio R. Caprile 7e668df1fe default to built-in TLS without preventing other choices 2024-11-13 17:29:44 -03:00
Sergey Lyubka 85414cfec2 Add extra step 2024-11-12 08:55:53 +00:00
robert b973187960 Use separate cookies for HTTP and HTTPS connections 2024-11-12 03:46:11 -05:00
Sergio R. Caprile 991080e613 Merge pull request #2963 from cesanta/uaws
unbreak AWS example and associated tests
2024-11-11 17:30:22 -03:00
Sergio R. Caprile 72bf199577 unbreak AWS example and associated tests 2024-11-11 17:27:59 -03:00
Sergio R. Caprile 7bda43a6ec Merge pull request #2962 from cesanta/picosdk
Pico-SDK support fixes and cleanups
2024-11-11 15:08:06 -03:00
Sergio R. Caprile 2b8b0ebe95 Pico-SDK support fixes and cleanups 2024-11-11 14:52:28 -03:00
Sergey Lyubka 0aa61ce58f Update build, use EC certs 2024-11-10 08:45:34 +00:00
Sergey Lyubka 51a5dc78d7 zip only web_root files 2024-11-09 08:09:50 +00:00
Sergio R. Caprile 232bd9a22b Merge pull request #2959 from cesanta/picosdk
Move ARCH_RP2040 --> ARCH_PICOSDK
2024-11-08 14:38:56 -03:00
Sergio R. Caprile 58327a1753 Move ARCH_RP2040 --> ARCH_PICOSDK 2024-11-08 14:34:33 -03:00
Sergio R. Caprile 7844d84798 Merge pull request #2956 from cesanta/ota-rt1170
OTA RT1170
2024-11-07 13:45:28 -03:00
Sergio R. Caprile 7a30a42797 Merge pull request #2957 from cesanta/picornd
Use Pico-SDK RNG
2024-11-07 11:59:47 -03:00
Sergio R. Caprile 094202ff16 Use Pico-SDK RNG 2024-11-07 11:57:08 -03:00
robert 9c4523f4fa OTA RT1170 2024-11-07 08:39:28 -05:00
Sergio R. Caprile 69859c61e0 Merge pull request #2955 from cesanta/ota-rt10xx
IMXRT OTA: support included for 1024, 1040, 1064
2024-11-07 09:32:05 -03:00
robert 9878518e29 IMXRT OTA: support included for 1024, 1040, 1064 2024-11-07 03:11:57 -05:00
robert cde270728f Fixed tms570 driver definition not being added to net_builtin 2024-11-07 03:09:18 -05:00
Sergio R. Caprile 5559d0fa68 Merge pull request #2953 from cesanta/otapico
Add OTA for Pico-SDK (RP2040)
2024-11-06 16:36:14 -03:00
Sergio R. Caprile 8feff78526 add tests 2024-11-06 11:40:57 -03:00
Sergey Lyubka 226a3de55d Fix dbl printing 2024-11-06 06:14:38 +00:00
Sergio R. Caprile 67d0f5f4ae Add OTA for Pico-SDK (RP2040) 2024-11-05 17:17:22 -03:00
Sergio R. Caprile 192f5e563c Merge pull request #2952 from cesanta/rt1020-ota-fix
RT1020 OTA: removed unnecessary compiler optimisation
2024-11-05 09:27:20 -03:00
robert b6296e7a67 RT1020 OTA: removed unnecessary compiler optimisation 2024-11-05 03:48:26 -05:00
Sergio R. Caprile 67e17d3bc3 Merge pull request #2951 from cesanta/inline
MG_IRAM -> noinline
2024-11-01 16:26:05 -03:00
Sergio R. Caprile 64a6fef823 MG_IRAM -> noinline 2024-11-01 16:21:18 -03:00
robertc2000 e0c64cc4ff Merge pull request #2949 from cesanta/ota-f7
STM32F OTA support
2024-10-30 16:57:21 +02:00
robert 3e55478b3b STM32F OTA support 2024-10-30 10:55:05 -04:00
Sergey Lyubka 9aef821862 Merge pull request #2933 from cesanta/win_rng
Windows: added alternative to bcrypt lib
2024-10-29 15:44:05 +00:00
robert f394df840e Killed bcrypt, replaced with rand_s 2024-10-29 10:41:10 -04:00
Sergey Lyubka 7d33699173 Merge pull request #2935 from cesanta/tms570
TMS570 support
2024-10-26 11:14:26 +01:00
Sergey Lyubka d3ffe8c647 Merge pull request #2947 from cesanta/ota
Simplify OTA API
2024-10-25 10:40:32 +01:00
Sergio R. Caprile 9b99f62311 Refactor OTA API 2024-10-24 19:08:06 -03:00
Sergey Lyubka 3319ce78d3 Simplify OTA API 2024-10-22 01:25:19 +01:00
Sergey Lyubka 8eabf43525 Failing tests 2024-10-16 12:58:25 +01:00
Sergio R. Caprile adb12bb7be nits 2024-10-11 14:12:46 -03:00
Sergio R. Caprile 3c10b36651 Merge pull request #2938 from cesanta/isresp
Honor c->is_resp with Connection:close
2024-10-10 19:47:59 -03:00
Sergio R. Caprile d37c300d87 Honor c->is_resp with Connection:close 2024-10-10 19:44:09 -03:00
Sergio R. Caprile 9fc92e901e Merge pull request #2936 from cesanta/test
Add/fix Zephyr tests (again)
2024-10-10 15:53:17 -03:00
Sergio R. Caprile 5b52529295 Add/fix Zephyr tests (again) 2024-10-10 15:49:53 -03:00
Sergio R. Caprile f77a7ad623 Merge pull request #2926 from cesanta/arp
Fix gw ARP. Make ARP probe public. Add ARP event
2024-10-10 11:44:50 -03:00
Sergio R. Caprile 504ef9422e fix gw ARP on startup 2024-10-10 11:42:38 -03:00
robert cbbcec0895 TMS570 support 2024-10-10 03:23:51 -04:00
Sergio R. Caprile 32d90c38db tweaks 2024-10-09 11:33:14 -03:00
Sergey Lyubka e1f7f3d7bb Make ARP probe public. Add ARP event 2024-10-09 11:33:14 -03:00
Sergio R. Caprile 244536ea72 Merge pull request #2934 from cesanta/test
Add test Makefiles for more IDEs
2024-10-08 18:58:32 -03:00
Sergio R. Caprile fa24a3e09e Add test Makefiles for more IDEs
Expand Wizard test script
2024-10-08 18:55:32 -03:00
robert 5ec26a5015 Windows: added alternative to bcrypt lib 2024-10-08 09:21:13 -04:00
Sergey Lyubka 8a8ff2aef0 Merge pull request #2908 from cesanta/convenience
avoid trashing other projs thinking redefining types is convenient
2024-10-05 08:49:17 +01:00
Sergio R. Caprile 069254be6a Merge pull request #2932 from cesanta/test
Add test Makefiles for IDEs and Wizard test script
2024-10-04 17:37:19 -03:00
Sergio R. Caprile f3cd74cb46 Add test Makefiles for IDEs
Add Wizard test script
2024-10-04 17:35:02 -03:00
Sergio R. Caprile 4be8aa0f91 Merge pull request #2919 from cesanta/frag
Fix IP fragmentation checks for big-endian CPUs
2024-10-04 14:02:14 -03:00
Sergey Lyubka 93dd7a85f6 Fix IP fragmentation checks for big-endian CPUs 2024-10-04 16:18:33 +01:00
Sergio R. Caprile 062596e3fb move to Wizard 2024-10-04 11:55:24 -03:00
Sergio R. Caprile 5af2de635e Merge pull request #2931 from cesanta/revert-2930-tw
Revert "test prod Wizard"
2024-10-04 11:50:55 -03:00
Sergio R. Caprile a16df91fbb Revert "test prod Wizard" 2024-10-04 11:50:41 -03:00
Sergio R. Caprile 44178b9103 Merge pull request #2930 from cesanta/tw
test prod Wizard
2024-10-03 17:10:31 -03:00
Sergio R. Caprile b767f930ad test prod Wizard 2024-10-03 17:09:16 -03:00
Sergio R. Caprile ba61a6545a move to Wizard 2024-10-03 16:50:00 -03:00
Sergio R. Caprile 23ada5c7a5 try to get abort texts from GH 2024-10-03 13:46:50 -03:00
Sergio R. Caprile 97c37efffe fix removed linked files 2024-10-03 13:26:18 -03:00
Sergio R. Caprile 5db95be4fc fix test file 2024-10-03 12:05:44 -03:00
Sergio R. Caprile 5897422c70 Merge pull request #2928 from cesanta/newskeleton
move to Wizard
2024-10-03 12:00:47 -03:00
Sergio R. Caprile a7db0d3cc5 move to Wizard 2024-10-03 11:55:38 -03:00
Sergey Lyubka c49036a713 Merge pull request #2921 from cesanta/dp83848
DP83848 has no clock setup
2024-10-03 11:44:26 +01:00
Sergio R. Caprile 03246997fa Merge pull request #2922 from cesanta/newskeleton
move to Wizard
2024-10-02 14:51:57 -03:00
Sergio R. Caprile f4eac6e4fc move to Wizard 2024-10-02 13:42:14 -03:00
Sergio R. Caprile 48f695f3e6 DP83848 has no clock setup 2024-10-02 10:22:09 -03:00
Sergio R. Caprile 3525f044f5 Merge pull request #2890 from cesanta/tls
Fix multiple TLS records in buffer
2024-10-01 18:30:04 -03:00
Sergio R. Caprile b58f8b9d7c Fix multiple TLS records in buffer 2024-10-01 18:26:51 -03:00
Sergio R. Caprile c00962e881 Merge pull request #2914 from cesanta/tests
fixes and improvements for tests
2024-09-27 18:50:51 -03:00
Sergio R. Caprile 9bcf1d662b fix tests 2024-09-27 18:33:26 -03:00
Sergio R. Caprile 586e0721d8 Merge pull request #2911 from cesanta/testcube
add Wizard examples
2024-09-26 20:30:41 -03:00
Sergio R. Caprile 882dd1f3a7 add Wizard examples 2024-09-26 20:20:00 -03:00
Sergio R. Caprile 399291d783 Merge pull request #2910 from cesanta/newskeleton
move to Wizard
2024-09-26 17:14:24 -03:00
Sergio R. Caprile 46ac2e5252 move to Wizard 2024-09-26 17:11:57 -03:00
Sergio R. Caprile a81818b2db avoid trashing other projs thinking redefining types is convenient 2024-09-24 20:14:39 -03:00
Sergio R. Caprile 9b0d112176 Merge pull request #2907 from cesanta/armcgt
Add ARMCGT arch
2024-09-24 19:01:28 -03:00
Sergio R. Caprile ac17df0c65 Add ARMCGT arch 2024-09-24 18:58:54 -03:00
Sergio R. Caprile c4be4e7928 Merge pull request #2906 from cesanta/revert-2901-fpp
Revert "fix printf precision handling"
2024-09-24 18:02:49 -03:00
Sergio R. Caprile 877cbbd11d Revert "fix printf precision handling" 2024-09-24 18:01:07 -03:00
Sergio R. Caprile b2bb03310e Merge pull request #2905 from cesanta/arpudp
Fix ARP handling with UDP
2024-09-24 14:22:52 -03:00
Sergio R. Caprile 5c8885ee5f Fix ARP handling with UDP 2024-09-24 12:37:13 -03:00
Sergio R. Caprile 40ec6b263d Merge pull request #2901 from cesanta/fpp
fix printf precision handling
2024-09-20 20:51:20 -03:00
Sergio R. Caprile 3742da8770 fix printf precision handling 2024-09-20 20:40:54 -03:00
Sergio R. Caprile 19b06418c5 Merge pull request #2899 from cesanta/examples
move to Wizard
2024-09-19 16:30:14 -03:00
Sergio R. Caprile b7b8b9219d move to Wizard 2024-09-19 16:25:36 -03:00
Sergio R. Caprile 949966964f Merge pull request #2896 from cesanta/examplesh563
move to Wizard
2024-09-18 19:47:50 -03:00
Sergio R. Caprile c0a0f9c1df Merge pull request #2895 from cesanta/examples
move to Wizard
2024-09-18 19:43:19 -03:00
Sergio R. Caprile 7cff2fa8f1 Merge pull request #2897 from cesanta/detach
Detach HTTP handler if MG_EV_HTTP_HDRS changes c->recv
2024-09-18 09:44:15 -03:00
Sergey Lyubka c1b703a039 Detach HTTP handler if MG_EV_HTTP_HDRS changes c->recv 2024-09-18 13:30:27 +01:00
Sergio R. Caprile e0eff1d2bb update CodeQL 2024-09-17 13:14:52 -03:00
Sergio R. Caprile 037ef76ad8 move to Wizard 2024-09-16 17:03:44 -03:00
Sergio R. Caprile ae8025cd5c move to Wizard 2024-09-16 16:52:37 -03:00
Sergio R. Caprile 1804cc3a09 fix CIFuxx 2024-09-16 14:34:40 -03:00
Sergio R. Caprile 2d8e6b45ec fix CIFuxx 2024-09-16 14:31:26 -03:00
Sergio R. Caprile 3fa52d0d7d fix outdated example 2024-09-16 11:06:08 -03:00
Sergey Lyubka 6a7129d7af Merge pull request #2884 from cesanta/examples
pilot move to new skeleton in examples
2024-09-12 08:07:16 +01:00
Sergey Lyubka f0e113a532 Merge pull request #2893 from cesanta/picow
Add Pico-W example
2024-09-12 07:53:10 +01:00
Sergio R. Caprile 8b3e415201 Add Pico-W example 2024-09-11 10:56:52 -03:00
Sergio R. Caprile eb6a8afe8d Merge pull request #2891 from cesanta/cflags
default to built-in TLS without preventing other choices
2024-09-09 14:07:37 -03:00
Sergio R. Caprile a705a89e4a default to built-in TLS without preventing other choices 2024-09-09 14:05:39 -03:00
Sergio R. Caprile ea509c0a36 move to Wizard 2024-09-05 11:48:20 -03:00
Sergio R. Caprile 269600d875 pilot move 2024-09-04 17:13:19 -03:00
Sergio R. Caprile 95e3a8f3cc Merge pull request #2882 from cesanta/phy
Add MG_TCPIP_PHY_CONF
2024-09-03 11:26:43 -03:00
Sergey Lyubka ffeff3ab69 Add MG_TCPIP_PHY_CONF 2024-09-03 15:07:27 +01:00
Sergio R. Caprile bdc009eb65 Merge pull request #2880 from cesanta/rng
Make mg_random() fallible. Abort TLS on weak RNG
2024-09-02 11:12:27 -03:00
Sergey Lyubka 683f65f8ac Make mg_random() fallible. Abort TLS on weak RNG 2024-09-02 11:06:10 -03:00
Sergey Lyubka a737698372 Merge pull request #2881 from cesanta/mime
Fix #2871 - accept `*` in mg_http_serve_opts::mime_types
2024-09-02 08:57:13 +01:00
Sergey Lyubka eeecbbcff9 Fix #2871 - accept * in mg_http_serve_opts::mime_types 2024-09-02 06:12:02 +01:00
Sergio R. Caprile 44b3d60692 Merge pull request #2877 from cesanta/iosize
MG_IO_SIZE=256 on embedded platforms
2024-08-30 15:54:48 -03:00
Sergey Lyubka 641c7d1967 MG_IO_SIZE=256 on embedded platforms 2024-08-30 15:52:14 -03:00
Sergey Lyubka 7923d1e930 Merge pull request #2875 from cesanta/iface
add macro to access mif
2024-08-29 21:44:42 +01:00
Sergio R. Caprile 42e072a868 add macro to access mif 2024-08-29 17:11:25 -03:00
Sergio R. Caprile 97296934ab update version 2024-08-21 09:33:12 -03:00
Sergey Lyubka 83dbe5fa3e Windows friendly 2024-08-17 08:20:41 +01:00
Sergio R. Caprile b566b8b45a Merge pull request #2862 from cesanta/fs
Disable POSIX FS by default
2024-08-14 11:43:05 -03:00
Sergey Lyubka ecdfda56c2 Disable POSIX FS by default 2024-08-14 05:26:08 +01:00
Sergio R. Caprile 166c4a244a Merge pull request #2861 from cesanta/modusoperandi
Fix Microchip breaking standards (at least until they do it again)
2024-08-12 12:27:41 -03:00
Sergio R. Caprile be7bfbac39 Fix Microchip breaking standards, as always 2024-08-12 12:20:21 -03:00
Sergio R. Caprile 3c8953672d Merge pull request #2860 from cesanta/l2r
fix ARP resolution when remote host is the gw
2024-08-12 12:03:05 -03:00
Sergio R. Caprile 045b196eeb fix ARP resolution when remote host is the gw 2024-08-12 11:55:57 -03:00
Sergio R. Caprile d763fce8ed Merge pull request #2851 from cesanta/tm4c
Update TM4C driver init + nits
2024-07-31 17:00:34 -03:00
Sergio R. Caprile 15c8ba5d3f Update TM4C driver init + nits 2024-07-31 16:53:29 -03:00
Sergio R. Caprile 1b75017c3c Merge pull request #2849 from cesanta/nit
improve close on TLS
2024-07-30 20:17:07 -03:00
Sergio R. Caprile 3ffe5e958f improve close on TLS 2024-07-30 19:30:14 -03:00
Sergio R. Caprile 4f6a78cde8 Merge pull request #2848 from cesanta/patchnxpphy
Patch KSZ PHY for NXP
2024-07-30 14:43:23 -03:00
Sergio R. Caprile 3081d0766b Patch KSZ PHY for NXP 2024-07-30 14:34:13 -03:00
Sergio R. Caprile c1e34cb9b5 Merge pull request #2847 from cesanta/frtcp
make friends with FreeRTOS+TCP compatibility
2024-07-30 11:33:57 -03:00
Sergio R. Caprile dedf67fb52 make friends with FreeRTOS+TCP compatibility 2024-07-30 10:58:10 -03:00
Sergey Lyubka a74fb940aa C89 compatibility for http-restful-server 2024-07-27 07:01:48 +01:00
Sergey Lyubka 09275ae4ca C89 compatibility for http-restful-server 2024-07-27 07:00:51 +01:00
Sergey Lyubka 657717d0fb Merge pull request #2846 from cesanta/tls
Move http-restful-server to builtin TLS, plus minor nits
2024-07-26 19:38:23 +01:00
Sergey Lyubka 4493d35d26 Move http-restful-server to builtin TLS, plus minor nits 2024-07-26 19:31:15 +01:00
Sergey Lyubka 0d26ce9bcc Merge pull request #2843 from cesanta/tlsoffset
Refactor tls receive pointer scheme (fix read after free)
2024-07-26 19:26:13 +01:00
Sergio R. Caprile fe77075996 Refactor tls receive pointer scheme 2024-07-26 12:15:05 -03:00
Sergio R. Caprile 4d6b126b9d unbreak after incorrect cleanup 2024-07-26 12:14:33 -03:00
Sergio R. Caprile 7b1900d547 Merge pull request #2845 from cesanta/tls
Misc TLS cleanups
2024-07-25 19:42:56 -03:00
Sergio R. Caprile 5a8c56e784 Misc TLS cleanups 2024-07-25 19:01:35 -03:00
Sergio R. Caprile 8c4cfc8101 rework fetch 2024-07-24 18:30:08 -03:00
Sergey Lyubka 5f1f5ffffd Add md5 endpoint for testing POST 2024-07-23 20:10:18 +01:00
Sergio R. Caprile 603c4b7672 Merge pull request #2842 from cesanta/pcap
Make net_builtin send client TLS HS
2024-07-23 15:04:41 -03:00
Sergey Lyubka 4b49c63344 Make net_builtin send client TLS HS 2024-07-23 18:47:48 +01:00
Sergio R. Caprile 9bdc910327 do proper connect 2024-07-23 14:35:32 -03:00
Sergio R. Caprile 730f50f770 Merge pull request #2839 from cesanta/miptst
improve MIP tests
2024-07-22 21:03:33 -03:00
Sergio R. Caprile 91606a9e3f improve MIP tests 2024-07-22 20:22:29 -03:00
Sergio R. Caprile 22b52f831b Merge pull request #2829 from cesanta/vli
allow building uECC with VLI
2024-07-10 12:17:10 -03:00
Sergio R. Caprile 071b3f558f allow building uECC with VLI 2024-07-10 12:01:28 -03:00
Sergio R. Caprile 59cd4004ac Merge pull request #2827 from cesanta/ws
handle possible memory trashing on mg_send() and mg_iobuf_add() failures
2024-07-09 15:01:36 -03:00
Sergio R. Caprile 7f7c1ff6c2 handle possible memory trashes on mg_send() and mg_iobuf_add() failures 2024-07-09 14:56:22 -03:00
Sergio R. Caprile ad3acf355e Merge pull request #2826 from cesanta/openwolf
SSLv23_ methods deprecated
2024-07-09 14:10:44 -03:00
Sergio R. Caprile 4dcc4e3308 SSL_CTX_new can fail
SSLv23_ methods deprecated
2024-07-09 14:08:55 -03:00
Sergio R. Caprile a9902b55d8 Merge pull request #2823 from cesanta/c89
Fix warnings and allow building chacha with C89 compilers
2024-07-08 19:05:30 -03:00
Sergio R. Caprile d46798c2a7 silence cast and c++ warnings) 2024-07-08 17:02:54 -03:00
Sergio R. Caprile 90623492b7 be more C89-friendly 2024-07-08 16:23:41 -03:00
Sergey Lyubka ddf3ba8a15 Squash vc98 chacha warnings 2024-07-07 10:29:52 +01:00
Sergio R. Caprile 0c4d33d558 fix Keil AWS FreeRTOS-plus-TCP 2024-07-04 17:31:11 -03:00
Sergey Lyubka 1c3b6ad59b Merge pull request #2817 from cesanta/chachachan
fix stack trashing
2024-07-04 05:57:06 +01:00
Sergio R. Caprile 473a12d700 Merge pull request #2807 from cesanta/tls
Fix raw TLS overflow for large uploads
2024-07-03 17:24:47 -03:00
Sergio R. Caprile 774cfc4bdc fix magic number 2024-07-03 17:16:32 -03:00
Sergey Lyubka 509fbcc4f8 Fix raw TLS overflow for large uploads 2024-07-03 16:40:04 -03:00
Sergio R. Caprile 00862344f7 fix stack trashing 2024-07-03 14:44:51 -03:00
Sergio R. Caprile 5ad2b0531a Merge pull request #2813 from cesanta/foureleven
fix 411 not draining header data
2024-07-01 14:50:13 -03:00
Sergio R. Caprile be8dbb0dc7 fix 411 not draining header data 2024-07-01 14:38:27 -03:00
Sergio R. Caprile bdfa0b302b Merge pull request #2809 from cesanta/tls2
Enable builtin TLS by default
2024-06-27 08:53:10 -03:00
Sergey Lyubka 7541304a9a Enable builtin TLS by default 2024-06-27 12:04:32 +01:00
Sergio R. Caprile 395a51eeca silence CodeQL 2024-06-26 11:59:52 -03:00
Sergey Lyubka 17e2d49c43 Merge pull request #2806 from cesanta/pipelined
resume pipelined reqs after serving a file
2024-06-26 14:13:15 +01:00
Sergey Lyubka ac71c320cd Merge pull request #2800 from cesanta/zephyr
avoid redefinitions
2024-06-26 14:12:06 +01:00
Sergio R. Caprile 0356bf6092 resume pipelined reqs after serving a file 2024-06-25 18:30:14 -03:00
Sergio R. Caprile 8bc1edd027 add unit tests 2024-06-25 17:03:48 -03:00
Sergio R. Caprile 403f0dc8a5 add unit tests 2024-06-25 16:47:41 -03:00
Sergio R. Caprile dffa198ebd Add tests for recent embedded targets 2024-06-25 15:08:35 -03:00
Sergio R. Caprile 7028417d88 Merge pull request #2794 from cesanta/close
handle `Connection: close`
2024-06-25 15:07:07 -03:00
Sergio R. Caprile 2d4ebba3ed Merge pull request #2805 from cesanta/plustcp
Update to latest FreeRTOS+TCP
2024-06-24 18:11:40 -03:00
Sergio R. Caprile aa3fda9c33 Update to latest FreeRTOS+TCP 2024-06-24 16:54:07 -03:00
Sergio R. Caprile 0f9f0b545e Merge pull request #2802 from cesanta/w5500
allow auto driver init
2024-06-21 18:53:41 -03:00
Sergio R. Caprile 9fcc398540 allow auto driver init 2024-06-21 17:12:07 -03:00
Sergio R. Caprile 61f4ab61cb avoid redefinitions 2024-06-19 11:39:10 -03:00
Sergio R. Caprile 1f481cbe54 Merge pull request #2799 from cesanta/zephyr
update to latest (again)
2024-06-19 09:48:07 -03:00
Sergio R. Caprile f4ee10a96a update to latest (again) 2024-06-18 20:56:31 -03:00
Sergio R. Caprile 9974be3fdc handle 'Connection: close' 2024-06-18 10:38:41 -03:00
Sergio R. Caprile 793171e9e0 Merge pull request #2793 from cesanta/tabs
Fix #2790 - allow tabs as the HTTP header whitespace
2024-06-17 11:41:18 -03:00
Sergio R. Caprile cee7087d54 do check 2024-06-17 11:38:32 -03:00
Sergey Lyubka f9bcffcbd5 Fix #2790 - allow tabs as the HTTP header whitespace 2024-06-17 12:01:32 +01:00
Sergey Lyubka 8fd7e87333 Merge pull request #2787 from cesanta/nicer
play nicer to intermediate OOMs in OpenSSL
2024-06-17 12:42:38 +02:00
Sergey Lyubka c436194d43 Fix #2789 - rename local var to avoid clash with system include 2024-06-17 11:41:37 +01:00
Sergio R. Caprile fcd160cc8c play nicer to intermediate OOMs in OpenSSL 2024-06-14 19:13:01 -03:00
Sergio R. Caprile 5adbadc901 make tests pass 2024-06-14 19:11:37 -03:00
Sergio R. Caprile 5084279d81 Merge pull request #2784 from cesanta/mcxn
add MCUXpresso examples for MCXN947
2024-06-13 13:45:48 -03:00
Sergio R. Caprile bd21d0d0cf add MCUXpresso examples for MCXN947 2024-06-13 13:43:53 -03:00
Sergio R. Caprile a3fd81540a Merge pull request #2783 from cesanta/mcxn
Update MCXN947 FreeRTOS to CM33 port
2024-06-12 17:04:45 -03:00
Sergio R. Caprile ba3f6a5e76 Update MCXN947 FreeRTOS to CM33 port 2024-06-12 17:00:10 -03:00
Sergio R. Caprile 25c56e86c9 Merge pull request #2780 from cesanta/sntp2
update example
2024-06-10 16:18:25 -03:00
Sergio R. Caprile 0897b0969d update example 2024-06-10 16:12:38 -03:00
Sergio R. Caprile 6cb1c3c0e9 Merge pull request #2778 from cesanta/tls7
Add mtls and chacha20
2024-06-10 11:36:40 -03:00
Sergey Lyubka df257a8e8a Add mtls and chacha20 2024-06-09 17:43:49 +01:00
Sergey Lyubka 71abdc1bda Merge pull request #2777 from cesanta/sntp
Add mg_now() to sntp.c
2024-06-09 08:50:36 +01:00
Sergey Lyubka 22de1dc0f2 Add mg_now() to sntp.c 2024-06-09 07:52:25 +01:00
Sergey Lyubka 6357b30712 More expressive variable names in SNTP 2024-06-08 09:00:08 +01:00
Sergio R. Caprile b0e18d5e8a Merge pull request #2775 from cesanta/dhcpdns
DNS and SNTP via DHCP
2024-06-05 14:41:57 -03:00
Sergio R. Caprile be58d73a0a DNS and SNTP via DHCP 2024-06-05 14:10:31 -03:00
Sergio R. Caprile c1f630f5ed Merge pull request #2772 from cesanta/strdup
bring mg_strdup() back
2024-05-31 18:05:59 -03:00
Sergio R. Caprile ab75bfa6e7 bring mg_strdup() back 2024-05-31 17:45:53 -03:00
Sergio R. Caprile a4e0225c69 Merge pull request #2771 from cesanta/mcxfr
Add FreeRTOS example
2024-05-30 20:08:38 -03:00
Sergio R. Caprile 6d3d6c3601 Add FreeRTOS example 2024-05-30 20:05:57 -03:00
Sergio R. Caprile 2872de75a0 Merge pull request #2770 from cesanta/1170fr
Add FreeRTOS example
2024-05-30 12:34:01 -03:00
Sergio R. Caprile 70936e3738 Add FreeRTOS example 2024-05-30 12:23:19 -03:00
Sergio R. Caprile c272883ec1 Merge pull request #2769 from cesanta/xmc7
XMC7: Ethernet descriptors 8-byte alignment
2024-05-29 13:31:23 -03:00
robert d9619a8fa4 XMC7: Ethernet descriptors 8-byte alignment 2024-05-29 10:48:53 -04:00
Sergey Lyubka 9ec2022447 Merge pull request #2767 from cesanta/frdm-n94
FRDM-MCXN947
2024-05-28 21:39:51 +01:00
Sergio R. Caprile 10f56c55e6 Add FRDM-MCXN947 2024-05-28 16:55:52 -03:00
robert 69682d6d97 Added N94 baremetal skeleton 2024-05-28 16:55:52 -03:00
Sergio R. Caprile b61575eb2b Merge pull request #2759 from cesanta/synpsys
Move stm32h driver to synopsys
2024-05-28 16:55:24 -03:00
Sergio R. Caprile 6942de4f57 Move stm32h driver to synopsys 2024-05-28 14:51:19 -03:00
Sergio R. Caprile 8085e21a05 Merge pull request #2766 from cesanta/xmc7
add 100/10M
2024-05-27 15:14:44 -03:00
Sergio R. Caprile 0061fe02e6 add 100/10M 2024-05-27 14:40:07 -03:00
1366 changed files with 43659 additions and 1008248 deletions

No files matched your search

+1
View File
@@ -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 actions were: _describe_
- My expectation was: _describe_
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
dry-run: false
language: c++
- name: Upload Crash
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
if: env.GO == 1 && failure() && steps.build.outcome == 'success'
with:
name: artifacts
+4 -4
View File
@@ -3,7 +3,7 @@ name: "CodeQL Scanning"
on:
schedule:
- cron: '30 2 * * *' # run at 2:30 AM UTC
- cron: '30 23 * * *' # run at 11:30 PM UTC
# Allow manual runs
workflow_dispatch:
@@ -17,11 +17,11 @@ jobs:
permissions:
security-events: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: cpp
- run: |
@@ -29,4 +29,4 @@ jobs:
./test/setup_ga_network.sh && make -C test mip_test CC=gcc ASAN= ASAN_OPTIONS=
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
+100 -56
View File
@@ -1,7 +1,7 @@
name: Full build and test
on:
schedule:
- cron: '0 1 * * *' # run at 1 AM UTC
- cron: '0 22 * * *' # run at 10 PM UTC
# Allow manual runs
workflow_dispatch:
env:
@@ -13,7 +13,7 @@ jobs:
fail-fast: false
matrix:
cc: [gcc, clang, g++, clang++]
target: [test, mip_test]
target: [test]
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"]
exclude:
@@ -37,7 +37,23 @@ jobs:
steps:
- uses: actions/checkout@v4
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:
runs-on: ubuntu-latest
strategy:
@@ -48,7 +64,7 @@ jobs:
steps:
- uses: actions/checkout@v4
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:
runs-on: ubuntu-latest
strategy:
@@ -59,7 +75,7 @@ jobs:
steps:
- uses: actions/checkout@v4
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:
runs-on: ubuntu-latest
strategy:
@@ -101,7 +117,7 @@ jobs:
name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
env:
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
steps:
- uses: actions/checkout@v4
@@ -154,7 +170,7 @@ jobs:
strategy:
fail-fast: false
matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
name: examples ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
@@ -285,10 +301,69 @@ jobs:
with: { fetch-depth: 2 }
- run: echo # nothing specific to install or do
- 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 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:
runs-on: ubuntu-latest
strategy:
@@ -304,7 +379,6 @@ jobs:
steps:
- uses: actions/checkout@v4
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: make -C examples/${{ matrix.example.path }} build
@@ -335,7 +409,7 @@ jobs:
- path: nxp/nxp-lpcxpresso54628-lwip-freertos
- path: nxp/nxp-twrk65f180m-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-f746zg-make-baremetal-builtin-rndis
- path: stm32/nucleo-g031-make-baremetal-builtin
@@ -370,30 +444,15 @@ jobs:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
example:
- path: microchip/same54-xpro/device-dashboard
- path: nxp/rt1020-evk-make-baremetal-builtin
- path: nxp/rt1020-evk-make-freertos-builtin
- path: nxp/rt1060-evk-make-baremetal-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: rp2040/pico-rndis-dashboard
- path: rp2040/pico-w
- path: rp2040/pico-w5500
- 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: pico-sdk/pico-rndis-dashboard
- path: pico-sdk/pico-w-picosdk-freertos-lwip
- path: pico-sdk/pico-2-w-picosdk-freertos-lwip
- path: stm32/nucleo-f746zg-make-freertos-tcp
- 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 }}
steps:
- uses: actions/checkout@v4
@@ -421,7 +480,7 @@ jobs:
fail-fast: false
matrix:
example:
- path: rp2040/pico-rndis-device
- path: pico-sdk/pico-rndis-device
name: ${{ matrix.example.path }}
steps:
- 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 }} 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:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: echo # nothing specific to install or do
- run: sudo pip install yq
- run: cd test/cube && make
zephyr_examples:
@@ -473,7 +517,7 @@ jobs:
- 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/zephyr init
- run: make -C examples/zephyr init REPO=zephyrprojectrtos/ci:v0.26.14 # "no space left on device" with newers
- name: minify manifest
uses: mikefarah/yq@master
with:
@@ -497,8 +541,8 @@ jobs:
- run: make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- name: Cube
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-freertos-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-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
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}}
- name: Cube
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-freertos-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-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
test_h743:
@@ -525,10 +569,10 @@ jobs:
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-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- name: Cube
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-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
# - name: Cube
# 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-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
test_h723:
runs-on: ubuntu-latest
@@ -578,7 +622,7 @@ jobs:
- name: baremetal
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-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:
runs-on: ubuntu-latest
@@ -617,5 +661,5 @@ jobs:
with: { fetch-depth: 2 }
- name: SDK
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
View File
@@ -25,7 +25,7 @@ jobs:
with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
- if: ${{ env.GO == 1 }}
run: ./test/setup_ga_network.sh && make -C test ${{ matrix.target }}
run: make -C test ${{ matrix.target }}
s390:
runs-on: ubuntu-latest
steps:
@@ -33,7 +33,7 @@ jobs:
with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
- 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:
runs-on: ubuntu-latest
steps:
@@ -41,7 +41,7 @@ jobs:
with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
- 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:
runs-on: ubuntu-latest
steps:
@@ -59,7 +59,7 @@ jobs:
name: macos SSL=${{ matrix.ssl }}
env:
SSL: ${{ matrix.ssl }}
TFLAGS: -DNO_SNTP_CHECK
#TFLAGS: -DNO_SNTP_CHECK
HOMEBREW_NO_AUTO_UPDATE: 1
steps:
- uses: actions/checkout@v4
@@ -173,6 +173,72 @@ jobs:
- 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:
runs-on: ubuntu-latest
strategy:
@@ -242,30 +308,15 @@ jobs:
matrix:
example:
- path: microchip/same54-xpro/device-dashboard
- path: nxp/rt1020-evk-make-baremetal-builtin
- path: nxp/rt1020-evk-make-freertos-builtin
- path: nxp/rt1060-evk-make-baremetal-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: rp2040/pico-rndis-dashboard
- path: rp2040/pico-w
- path: rp2040/pico-w5500
- 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: pico-sdk/pico-rndis-dashboard
- path: pico-sdk/pico-w-picosdk-freertos-lwip
- path: pico-sdk/pico-2-w-picosdk-freertos-lwip
- path: stm32/nucleo-f746zg-make-freertos-tcp
- 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 }}
env:
GO: 0
@@ -307,7 +358,7 @@ jobs:
fail-fast: false
matrix:
example:
- path: rp2040/pico-rndis-device
- path: pico-sdk/pico-rndis-device
name: ${{ matrix.example.path }}
env:
GO: 0
@@ -322,64 +373,6 @@ jobs:
- if: ${{ env.GO == 1 }}
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:
runs-on: ubuntu-latest
env:
@@ -390,7 +383,7 @@ jobs:
- run: |
if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-*-cube-*'; then
echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do
sudo pip install yq
fi
- if: ${{ env.GO == 1 }}
run: cd test/cube && make
@@ -432,16 +425,16 @@ jobs:
echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do
fi
- if: ${{ env.GO == 1 }}
run: |
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
fi
- if: ${{ env.GO == 1 }}
run: |
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
fi
# - if: ${{ env.GO == 1 }}
# run: |
# 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
# fi
# - if: ${{ env.GO == 1 }}
# run: |
# 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
# fi
- if: ${{ env.GO == 1 }}
run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-freertos-lwip'; then
@@ -480,16 +473,16 @@ jobs:
echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do
fi
- if: ${{ env.GO == 1 }}
run: |
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
fi
- if: ${{ env.GO == 1 }}
run: |
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
fi
# - if: ${{ env.GO == 1 }}
# run: |
# 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
# fi
# - if: ${{ env.GO == 1 }}
# run: |
# 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
# fi
- if: ${{ env.GO == 1 }}
run: |
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
make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi
- name: Cube
run: |
echo GO=0 >> $GITHUB_ENV
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h74.*-cube-'; then
echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do
fi
- if: ${{ env.GO == 1 }}
run: |
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
fi
- if: ${{ env.GO == 1 }}
run: |
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
fi
# - name: Cube
# run: |
# echo GO=0 >> $GITHUB_ENV
# if ./test/match_changed_files.sh 'examples/stm32/nucleo-h74.*-cube-'; then
# echo GO=1 >> $GITHUB_ENV
# # nothing specific to install or do
# fi
# - if: ${{ env.GO == 1 }}
# run: |
# 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
# fi
# - if: ${{ env.GO == 1 }}
# run: |
# 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
# fi
test_h723:
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
make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi
# - if: ${{ env.GO == 1 }}
# run: |
# 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}}
# fi
- if: ${{ env.GO == 1 }}
run: |
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}}
fi
test_ra6m4:
runs-on: ubuntu-latest
@@ -745,10 +738,10 @@ jobs:
with: { fetch-depth: 2 }
- name: SDK
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
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi
- 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 -1
View File
@@ -1,5 +1,5 @@
Copyright (c) 2004-2013 Sergey Lyubka
Copyright (c) 2013-2024 Cesanta Software Limited
Copyright (c) 2013-2025 Cesanta Software Limited
All rights reserved
This software is dual-licensed: you can redistribute it and/or modify
+3 -2
View File
@@ -4,6 +4,7 @@
[![Build Status]( https://github.com/cesanta/mongoose/workflows/build/badge.svg)](https://github.com/cesanta/mongoose/actions)
[![Code Coverage](https://codecov.io/gh/cesanta/mongoose/branch/master/graph/badge.svg)](https://codecov.io/gh/cesanta/mongoose)
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/mongoose.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
[![Gurubase](https://img.shields.io/badge/Gurubase-Ask%20Mongoose%20Guru-006BFF)](https://gurubase.io/g/mongoose)
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
@@ -14,7 +15,7 @@ robust, and easy. Features include:
- Cross-platform:
- 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
- ideal for the unification of the network infrastructure code across company
- 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) {
if (ev == MG_EV_HTTP_MSG) {
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));
} else {
mg_http_reply(c, 500, "", "{%m:%m}\n", MG_ESC("error"), MG_ESC("Unsupported URI"));
+13
View File
@@ -14,6 +14,7 @@ arduino-xiao-board:
./arduino/arduino --install-boards Seeeduino:samd
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-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-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:
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;
}
@@ -0,0 +1,3 @@
#pragma once
#define MG_ARCH MG_ARCH_ESP32
+102
View File
@@ -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;
}
@@ -0,0 +1,3 @@
#pragma once
#define MG_ARCH MG_ARCH_ESP32
@@ -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>
#define MG_ARCH MG_ARCH_CUSTOM
#define MG_ENABLE_SOCKET 0
#define MG_ENABLE_TCPIP 1
#define MG_ENABLE_DRIVER_W5500 1
#define mkdir(a, b) (-1)
#define MG_IO_SIZE 128
//#define MG_ENABLE_LOG 0
#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 256
+95 -34
View File
@@ -1,47 +1,108 @@
#include <SPI.h>
#include "mongoose.h"
#define SS_PIN 3 // Slave select pin
struct mg_mgr mgr; // Mongoose event manager
#define LED_PIN LED_BUILTIN // LED pin
#define SS_PIN 17 // Slave select pin for the W5500 module
struct mg_tcpip_spi spi = {
NULL, // SPI data
[](void *) { digitalWrite(SS_PIN, LOW); }, // begin transation
[](void *) { digitalWrite(SS_PIN, HIGH); }, // end transaction
[](void *, uint8_t c) { return SPI.transfer(c); }, // execute transaction
NULL, // SPI metadata
[](void *) { digitalWrite(SS_PIN, LOW); SPI.beginTransaction(SPISettings()); },
[](void *) { digitalWrite(SS_PIN, HIGH); SPI.endTransaction(); },
[](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() {
Serial.begin(115200);
pinMode(SS_PIN, OUTPUT);
SPI.begin();
Serial.begin(115200); // Initialise serial
while (!Serial) delay(50); // for debug output
// Set logging function to a serial print
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
mg_mgr_init(&mgr);
SPI.begin(); // Iniitialise SPI
pinMode(SS_PIN, OUTPUT); // to communicate with W5500 Ethernet module
pinMode(LED_PIN, OUTPUT); // Initialise LED
delay(3000);
MG_INFO(("Starting TCP/IP stack..."));
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
mif.driver = &mg_tcpip_driver_w5500;
mif.driver_data = &spi;
mg_tcpip_init(&mgr, &mif);
// 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);
// Setup HTTP & HTTPS listeners. Respond "ok" on any HTTP request
mg_http_listen(&mgr, "http://0.0.0.0:80", http_ev_handler, NULL);
mg_http_listen(&mgr, "https://0.0.0.0:443", http_ev_handler, (void *) 1);
}
void loop() {
@@ -11,6 +11,10 @@
#define MG_ENABLE_SOCKET 0
#define MG_ENABLE_TCPIP 1
#define MG_ENABLE_DRIVER_W5500 1
#define mkdir(a, b) (-1)
#define MG_IO_SIZE 512
//#define MG_ENABLE_LOG 0
#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
-58
View File
@@ -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);
}
-16
View File
@@ -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
+88 -36
View File
@@ -1,51 +1,103 @@
#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 = {
NULL, // SPI data
[](void *) { digitalWrite(SS_PIN, LOW); }, // Begin transaction
[](void *) { digitalWrite(SS_PIN, HIGH); }, // End transaction
[](void *, uint8_t c) { return SPI.transfer(c); }, // Execute transaction
NULL, // SPI metadata
[](void *) { digitalWrite(SS_PIN, LOW); SPI.beginTransaction(SPISettings()); },
[](void *) { digitalWrite(SS_PIN, HIGH); SPI.endTransaction(); },
[](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) {
char res[100];
if (req_len == 2 && strncmp(req, "on", req_len) == 0) {
digitalWrite(LED_BUILTIN, true);
snprintf(res, sizeof(res), "LED on");
} else if (req_len == 3 && strncmp(req, "off", req_len) == 0) {
digitalWrite(LED_BUILTIN, false);
snprintf(res, sizeof(res), "LED off");
} else {
snprintf(res, sizeof(res), "Unknown command: [%.*s]", (int) req_len, req);
}
Serial.println(res);
mqtt_publish(res);
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;
}
static void process_input(char c) {
static char buf[100];
static size_t len = 0;
char response[100];
if (c != '\n' && c != '\0') buf[len++] = c; // Append to the buffer
if (len >= sizeof(buf)) len = 0; // On overflow, reset
if (c == '\n' && len > 0) {
exec_command(buf, len);
len = 0;
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 (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);
SPI.begin();
pinMode(SS_PIN, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
net_init();
Serial.begin(115200); // Initialise serial
while (!Serial) delay(50); // for debug output
SPI.begin(); // Iniitialise SPI
pinMode(SS_PIN, OUTPUT); // to communicate with W5500 Ethernet module
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() {
if (Serial.available()) process_input(Serial.read());
mg_mgr_poll(&mgr, 1);
mg_mgr_poll(&mgr, 1); // Process network events
reconnect_if_not_connected(); // Reconnect to MQTT server if needed
}
+8 -76
View File
@@ -26,12 +26,6 @@ static struct settings s_settings = {true, 1, 57, NULL};
static const char *s_json_header =
"Content-Type: application/json\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) {
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;
}
// 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
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
@@ -98,19 +77,22 @@ static struct user *authenticate(struct mg_http_message *hm) {
static void handle_login(struct mg_connection *c, struct user *u) {
char cookie[256];
const char *cookie_name = c->is_tls ? "secure_access_token" : "access_token";
mg_snprintf(cookie, sizeof(cookie),
"Set-Cookie: access_token=%s; Path=/; "
"Set-Cookie: %s=%s; Path=/; "
"%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));
}
static void handle_logout(struct mg_connection *c) {
char cookie[256];
const char *cookie_name = c->is_tls ? "secure_access_token" : "access_token";
mg_snprintf(cookie, sizeof(cookie),
"Set-Cookie: access_token=; Path=/; "
"Set-Cookie: %s=; Path=/; "
"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; " : "");
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);
} else {
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
static void fn(struct mg_connection *c, int ev, void *ev_data) {
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);
} else if (mg_match(hm->uri, mg_str("/api/firmware/upload"), NULL)) {
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 {
struct mg_http_serve_opts opts;
memset(&opts, 0, sizeof(opts));
+17 -10
View File
@@ -27,7 +27,15 @@ void app_main(void) {
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) {
return NULL;
}
@@ -57,9 +65,7 @@ bool mg_flash_write(void *addr, const void *buf, size_t len) {
void mg_device_reset(void) {
esp_restart();
}
#endif
#if MG_OTA == MG_OTA_CUSTOM
#include "esp_app_format.h"
#include "esp_ota_ops.h"
@@ -121,6 +127,14 @@ bool check_fw_header(const void* buf, size_t len) {
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) {
rx_checked = false;
if (s_size) {
@@ -255,11 +269,4 @@ uint32_t mg_ota_timestamp(int fw) {
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
@@ -3,4 +3,3 @@
#define MG_ENABLE_PACKED_FS 1
#define MG_TLS MG_TLS_NONE // change to 'MG_TLS_MBED' to enable TLS
#define MG_OTA MG_OTA_CUSTOM
#define MG_DEVICE MG_DEVICE_CUSTOM
+22 -34
View File
@@ -1,41 +1,29 @@
CFLAGS = -W -Wall -Werror -Wextra -Wundef -Wshadow -Wdouble-promotion
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_xmc7/devices/COMPONENT_CAT1C/include/
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
BOARD = xmc7200
IDE = GCC+make
RTOS = baremetal
WIZARD_URL ?= http://mongoose.ws/wizard
all build example: firmware.bin
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
firmware.bin: wizard
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
firmware.elf: cmsis_core cmsis_xmc7 $(SOURCES) hal.h link.ld Makefile
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
arm-none-eabi-size $@
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
cmsis_core: # ARM CMSIS core headers
git clone -q --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
cmsis_xmc7:
git clone https://github.com/Infineon/mtb-pdl-cat1.git $@
echo "" > cmsis_xmc7/devices/COMPONENT_CAT1C/include/ip/system_cat1c.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=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:
$(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)
-146
View File
@@ -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__
-244
View File
@@ -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 = .;
}
-32
View File
@@ -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:
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
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
# 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
}
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)) {
uint32_t r = rng_read();
memcpy((char *) buf + n, &r, n + sizeof(r) > len ? len - n : sizeof(r));
}
return true;
}
static void timer_fn(void *arg) {
@@ -36,7 +36,7 @@ flash: firmware.bin
cmsis_core:
git clone --depth 1 -b 5.9.0 https://github.com/ARM-software/CMSIS_5 $@
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
# 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
}
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)) {
uint32_t r = rng_read();
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) {
+1 -23
View File
@@ -22,7 +22,6 @@ static struct device_settings s_settings;
static const char *s_json_header =
"Content-Type: application/json\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) {
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");
}
// 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
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,
@@ -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)) {
handle_modbus_exec(c, hm->body);
} 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");
} else {
struct mg_http_serve_opts opts;
+3 -5
View File
@@ -1,14 +1,12 @@
PWD := $(shell pwd)
NPX ?= npx
all: bundle.js main.css
make -C ../../../tutorials/http/http-server ARGS="-d $(PWD)"
all:
make -C ../../../tutorials/http/http-server ARGS="-d $(CURDIR)"
# Bundle JS libraries (preact, preact-router, ...) into a single file
bundle.js:
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
NPX ?= npx
main.css: index.html $(wildcard *.js)
$(NPX) tailwindcss -o $@ --minify
+6 -65
View File
@@ -20,11 +20,6 @@ struct 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
// 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);
}
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) {
uint16_t *array = va_arg(*ap, uint16_t *);
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
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("status"), MG_ESC("online"), //
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,
s_device_config.pin_count, //
MG_ESC(("pin_state")), print_bools, s_device_config.pin_state,
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);
s_device_config.pin_count);
memset(&pub_opts, 0, sizeof(pub_opts));
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) {
long ofs = mg_json_get_long(r->frame, "$.params.offset", -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);
} else {
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);
}
@@ -277,26 +236,11 @@ static void timer_ping(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 uint64_t hourly_timer = 0;
if (s_boot_timestamp == 0 ||
mg_timer_expired(&hourly_timer, 3600000, mg_millis())) {
mg_sntp_connect(param, "udp://time.google.com:123", sntp_ev_handler, NULL);
uint64_t t1 = mg_now(), t2 = mg_millis();
if (t1 < t2 + 3600 || mg_timer_expired(&hourly_timer, 3600000, t2)) {
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
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("device.reset"), rpc_device_reset, NULL);
mg_timer_add(mgr, 3000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_reconnect,
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
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1021
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
BOARD = rt1020
IDE = GCC+make
RTOS = baremetal
WIZARD_URL ?= http://mongoose.ws/wizard
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
ram: LDSCRIPT = link_ram.ld
ram: firmware.bin
firmware.bin: wizard
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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/
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/4
update: firmware.bin
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
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
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:
$(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
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1021
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
BOARD = rt1020
IDE = GCC+make
RTOS = FreeRTOS
WIZARD_URL ?= http://mongoose.ws/wizard
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
ram: LDSCRIPT = link_ram.ld
ram: firmware.bin
firmware.bin: wizard
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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/
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/4
update: firmware.bin
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
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
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:
$(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
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1062
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
BOARD = rt1060
IDE = GCC+make
RTOS = baremetal
WIZARD_URL ?= http://mongoose.ws/wizard
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
ram: LDSCRIPT = link_ram.ld
ram: firmware.bin
firmware.bin: wizard
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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/
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/13
update: firmware.bin
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
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
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:
$(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
CFLAGS += -Wformat-truncation -fno-common # -Wconversion is not SDK-friendly
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include -Icmsis_mcu/devices/MIMXRT1062
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
BOARD = rt1060
IDE = GCC+make
RTOS = FreeRTOS
WIZARD_URL ?= http://mongoose.ws/wizard
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
ram: LDSCRIPT = link_ram.ld
ram: firmware.bin
firmware.bin: wizard
make -C wizard CFLAGS_EXTRA=$(CFLAGS_EXTRA) && mv wizard/firmware.bin ./
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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/
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/13
update: firmware.bin
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
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
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:
$(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