Compare commits

...
440 Commits
Author SHA1 Message Date
Sergio R. Caprile ccfe7e0724 update version 2025-05-21 09:46:14 -03:00
Sergio R. Caprile 8061a41b38 workaround 2025-05-19 09:22:59 -03:00
Sergio R. Caprile 39392b3690 Merge pull request #3139 from cesanta/freewill
free ifp on mgr_free
2025-05-15 18:04:42 -03:00
Sergio R. Caprile 54d4611eb6 call mg_tcpip_free from mg_mgr_free() 2025-05-15 17:37:40 -03:00
Sergio R. Caprile 34cdce750d Merge pull request #3138 from cesanta/pedantic
make clang happy
2025-05-15 17:11:22 -03:00
Sergio R. Caprile f3fafb6759 make clang happy 2025-05-15 17:09:29 -03:00
Sergio R. Caprile 0372c97ff5 add fuzz 2025-05-15 16:48:16 -03:00
Sergio R. Caprile b46136a0af Merge pull request #3137 from cesanta/testtls
add fuzz tests
2025-05-15 16:33:17 -03:00
Sergio R. Caprile ac3d41fb79 add fuzz tests 2025-05-15 16:32:42 -03:00
Sergio R. Caprile 14be42c868 INFO -> VERBOSE 2025-05-15 15:50:36 -03:00
robertc2000 f0ec14543a Merge pull request #3136 from cesanta/ra6-driver-init
RA6 driver init macro
2025-05-15 10:20:31 +03:00
robert f46c5b7214 RA6 driver init macro 2025-05-15 03:13:49 -04:00
Sergey Lyubka ccd6bcd95f Merge pull request #3132 from cesanta/tls
stronger bounds checking
2025-05-13 22:26:35 +01:00
Sergey Lyubka a3b63f3b0d Merge pull request #3130 from cesanta/longpost
fix broken TCP closure
2025-05-13 22:26:15 +01:00
Sergey Lyubka f2905a5e10 Merge pull request #3135 from cesanta/mss
Handle (specific) TCP options
2025-05-13 22:25:52 +01:00
Sergio R. Caprile 1ef6c6aeb5 Handle TCP options 2025-05-13 16:27:50 -03:00
robertc2000 bd53529b45 Merge pull request #3134 from cesanta/ota-rw612
OTA for FRDM-RW612
2025-05-13 10:33:41 +03:00
Sergio R. Caprile cc8ecc5a42 stronger bounds checking 2025-05-12 18:13:41 -03:00
robert 5a816a1d41 OTA for FRDM-RW612 2025-05-12 07:59:15 -04:00
robertc2000 9922286c67 Merge pull request #3131 from cesanta/ws-offset
Websocket offset validation enhancement
2025-05-09 13:05:20 +03:00
robert cdc439bc38 Websocket offset validation enhancement 2025-05-09 06:04:34 -04:00
Sergio R. Caprile ae8422e304 fix broken TCP closure 2025-05-08 13:40:02 -03:00
robert 539d080346 check null pointer 2025-05-07 08:40:07 -04:00
Sergey Lyubka 041ec6e1f8 Close if drained 2025-05-03 10:28:40 +01:00
Sergio R. Caprile f618fe125c Fix lwIP builds
fixes #3119

lwIP does not export ip_mreq by default, it requires enabling support for IGMP by setting LWIP_IGMP, with the associated extra stuff. Mongoose will print an error if mg_multicast_add() is called with no multicast support in lwIP.
2025-04-29 19:24:17 -03:00
Sergio R. Caprile 8ab514fabc make hexdump send CRLF 2025-04-28 12:33:31 -03:00
novlean 08ad2c3145 Merge pull request #3113 from cesanta/novlean-patch-2
Update README.md
2025-04-24 17:40:00 +01:00
novlean c64fd404d4 Update README.md
article
2025-04-24 17:39:51 +01:00
Sergio R. Caprile 143b0ac126 fix 2025-04-24 11:04:43 -03:00
Sergio R. Caprile c2e2432010 Merge pull request #3093 from cesanta/mdns-multicast
Added MDNS and driver support for multicast
2025-04-22 14:01:34 -03:00
Sergio R. Caprile 1d2a768184 refactor the rest of the drivers 2025-04-22 13:59:03 -03:00
novlean fb099641bc Merge pull request #3111 from cesanta/novlean-patch-2
Update README.md
2025-04-22 17:48:28 +01:00
novlean 6da9afbf29 Update README.md 2025-04-22 17:48:12 +01:00
Sergio R. Caprile dceb4beb09 Refactor MIP strategy and first driver (CMSIS) 2025-04-22 12:55:21 -03:00
robert 6f697db49d Added MDNS and driver support for multicast 2025-04-22 12:55:15 -03:00
Sergio R. Caprile b44193780e Merge pull request #3110 from cesanta/tlsfindata
Fix not reading last TLS small record with fast closure
2025-04-22 10:03:40 -03:00
Sergio R. Caprile 8e0212c3db Fix not reading last TLS small record with fast closure
Fixes #3104
MbedTLS API fairplay
2025-04-22 09:56:49 -03:00
Sergio R. Caprile 3861e2e1e7 Merge pull request #3097 from cesanta/builtdoze
fix missing weird types
2025-04-14 13:13:06 -03:00
Sergio R. Caprile 21eefa4b55 Merge pull request #3102 from cesanta/mipfin
Fix handling of FIN segments carrying data
2025-04-14 11:27:09 -03:00
Sergey Lyubka fb6c6aafeb Merge pull request #3100 from cesanta/timers
Fix #2768 - remove completed timers
2025-04-14 15:15:36 +01:00
Sergio R. Caprile df07426e78 Fix handling of FIN segments carrying data 2025-04-14 11:11:48 -03:00
Sergio R. Caprile 5cf1523a13 Merge pull request #3101 from cesanta/tlszero
workaround causing TLS libs to return zero
2025-04-14 10:40:36 -03:00
Sergio R. Caprile f2fe47e9f7 workaround causing TLS libs to return zero 2025-04-11 14:42:15 -03:00
Sergio R. Caprile 2557ab2e60 Merge pull request #3086 from cesanta/cywst
Add support for RM2 with STM32F (429, 746)
2025-04-11 09:28:25 -03:00
Sergio R. Caprile fbc1708000 Add support for RM2 with STM32F (429, 746) 2025-04-11 09:20:40 -03:00
Sergey Lyubka 0539cf1023 Fix #2768 - remove completed timers 2025-04-11 11:24:10 +01:00
Sergio R. Caprile 07b410447b fix missing weird types 2025-04-10 10:02:20 -03:00
Sergey Lyubka fb69016196 Merge pull request #3096 from cesanta/polldoze
allow other stack than WinSock in Windows
2025-04-10 07:21:29 +01:00
Sergio R. Caprile 169cbc044f Merge pull request #3095 from cesanta/noVLA
no VLA
2025-04-09 13:28:21 -03:00
Sergio R. Caprile 08091d02e5 allow other stack than WinSock in Windows 2025-04-09 12:05:01 -03:00
Sergio R. Caprile 6f2dcf92a7 no VLA 2025-04-09 10:55:54 -03:00
Sergio R. Caprile 578e52618d Merge pull request #3092 from cesanta/picofix
unbreak pico[2]W auto init
2025-04-07 16:00:33 -03:00
Sergio R. Caprile ec0fe66a17 unbreak pico[2]W auto init 2025-04-07 15:56:11 -03:00
novlean 8fee24291a Merge pull request #3091 from cesanta/novlean-patch-2
Update README.md
2025-04-07 17:53:34 +01:00
novlean 05bba2958d Update README.md
Articles
2025-04-07 17:53:22 +01:00
robert e656b1c792 Removed alloca call for ARM-CGT compatibility 2025-04-07 09:08:22 -04:00
Sergey Lyubka e0ccbadd25 Merge pull request #3083 from cesanta/cyw
Introducing CYW driver and Wi-Fi AP support
2025-03-30 11:27:56 +01:00
Sergey Lyubka 40a2a8822f Squash warning 2025-03-29 18:59:01 +00:00
Sergio R. Caprile e2ee356a87 Merge pull request #3084 from cesanta/2ap
Add support for AP in Pico 2 W (valid for Pico W)
2025-03-28 09:51:15 -03:00
Sergio R. Caprile 189bef61d3 Add support for AP in Pico 2 W (valid for Pico W) 2025-03-24 17:49:40 -03:00
Sergio R. Caprile 7d94f9f61b Add Pico + RM2 Wi-Fi example 2025-03-24 17:41:12 -03:00
Sergio R. Caprile e37a0b9056 Add CYW driver 2025-03-24 17:03:05 -03:00
Sergio R. Caprile 0b57b23951 Add support for Wi-Fi chip drivers 2025-03-24 17:02:50 -03:00
Sergey Lyubka c84826e84e Merge pull request #3081 from cesanta/dhcp
Allow user to set custom DHCP name
2025-03-24 08:01:43 +00:00
Sergey Lyubka 064fc6ff7b Allow user to set custom DHCP name 2025-03-22 16:30:02 +00:00
Sergio R. Caprile 042ea53478 Merge pull request #3076 from cesanta/mondirw
keep up with Wizard dir structure
2025-03-12 17:14:30 -03:00
Sergio R. Caprile 900b0acf7a keep up with Wizard dir structure 2025-03-12 17:08:36 -03:00
Sergio R. Caprile dc5f2e295a Merge pull request #3074 from cesanta/wait
fix IO_WAIT on send for builtin TLS and MbedTLS
2025-03-11 16:21:32 -03:00
Sergio R. Caprile c1849c2b19 fix IO_WAIT on send for builtin TLS and MbedTLS 2025-03-11 16:14:12 -03:00
Sergio R. Caprile 4eadf3699f unbreak C89 2025-03-11 16:00:42 -03:00
Sergio R. Caprile b30cf6587c Merge pull request #3072 from cesanta/rw612-wifi-xpresso
RW612 MCUXpresso WiFi example with FreeRTOS and LWIP
2025-03-08 14:56:29 -03:00
Sergio R. Caprile fbc231f33e Merge pull request #3070 from cesanta/hton
remove memcpy from htons/l and test load/save bigendian macros
2025-03-08 14:46:46 -03:00
Sergio R. Caprile bc8c839342 Merge pull request #3033 from cesanta/wifi
Change driver API: up(ifp) -> poll(ifp, 1second)
2025-03-08 11:40:39 -03:00
Sergio R. Caprile 90a23fe230 Add support for Wi-Fi chip drivers 2025-03-07 16:41:33 -03:00
Sergio R. Caprile 065027843e Change driver API: up(ifp) -> poll(ifp, 1second)
Add misc extras required by Wi-Fi drivers (in progress)
2025-03-07 14:14:16 -03:00
Sergio R. Caprile 8906b1ac0f Merge pull request #3025 from cesanta/ub
fix UB and possible exception trigger
2025-03-07 13:49:37 -03:00
robert 05f9e61a41 RW612 MCUXpresso WiFi example with FreeRTOS and LWIP 2025-03-07 11:12:30 -05:00
Sergio R. Caprile 782896b5d3 remove memcpy from htons/l 2025-03-05 17:20:35 -03:00
Sergio R. Caprile 4258f62560 Merge pull request #3069 from cesanta/beduino
add test for ESP32
2025-03-05 14:23:05 -03:00
Sergio R. Caprile 537ba64a54 add test for ESP32 2025-03-05 12:34:22 -03:00
Sergey Lyubka 25d20b7354 Add mg_tcpip_driver_w5100 to the header 2025-03-05 06:54:20 +00:00
Sergio R. Caprile 04d8362905 Merge pull request #3068 from cesanta/arduino
fix Arduino tests
2025-03-04 16:31:57 -03:00
Sergio R. Caprile 21266e9a45 fix Arduino tests 2025-03-04 16:20:18 -03:00
Sergio R. Caprile 7304e2171d Merge pull request #3065 from cesanta/reduino
Rename conflictive macros, add and refactor crypto tests
2025-03-04 12:11:45 -03:00
Sergio R. Caprile 61fc480850 Rename conflictive macros, refactor crypto tests 2025-03-04 11:55:57 -03:00
robertc2000 562e82f5ac Merge pull request #3059 from cesanta/ota-rt1050
OTA on RT1050
2025-03-03 10:09:27 +02:00
robert d7ff85bb48 OTA on RT1050 2025-03-03 03:03:28 -05:00
Sergio R. Caprile 55bc6105e1 Merge pull request #3058 from cesanta/move
move examples -> tutorials
2025-02-28 14:00:06 -03:00
Sergio R. Caprile 306c0b6096 move examples -> tutorials 2025-02-28 13:55:57 -03:00
Sergio R. Caprile 024078ae33 Merge pull request #3057 from cesanta/move
move vendors -> tutorials
2025-02-28 10:10:07 -03:00
Sergio R. Caprile b5a9ba8390 move vendors -> tutorials 2025-02-28 10:01:51 -03:00
Sergey Lyubka 93f36927ca Add .mjs mime type 2025-02-27 16:50:04 +00:00
Sergio R. Caprile 1db90cafd1 Merge pull request #3056 from cesanta/move
move Zephyr -> tutorials
2025-02-27 12:02:48 -03:00
Sergio R. Caprile bf23a0def7 move Zephyr -> tutorials 2025-02-27 10:57:08 -03:00
Sergio R. Caprile ea1cbeea9d Merge pull request #3054 from cesanta/move
move UART bridge -> tutorials
2025-02-26 15:11:27 -03:00
Sergio R. Caprile aeda7e5520 move UART bridge -> tutorials 2025-02-26 15:08:06 -03:00
Sergio R. Caprile a7899af8b8 Merge pull request #3053 from cesanta/move
move ESP32 device dashboard -> tutorials
2025-02-26 14:17:06 -03:00
Sergio R. Caprile b0385f47af move ESP32 device dashboard -> tutorials 2025-02-26 14:14:08 -03:00
Sergio R. Caprile 86c384657c Merge pull request #3052 from cesanta/move
integrate reference-projects into existing tutorials
2025-02-26 12:05:14 -03:00
Sergio R. Caprile 6e569110d2 integrate reference-projects intto existing tutorials 2025-02-26 12:00:46 -03:00
Sergio R. Caprile 3b1024b13c Merge pull request #3051 from cesanta/move
move MicroPython and dashboards -> tutorials
2025-02-26 11:43:14 -03:00
Sergio R. Caprile b3f5d11275 move MicroPython and dashboards -> tutorials 2025-02-26 11:31:01 -03:00
Sergio R. Caprile 1078ba0a92 Merge pull request #3050 from cesanta/move
move file-transfer -> tutorials
2025-02-25 16:54:25 -03:00
Sergio R. Caprile 005c8170d4 move file-transfer -> tutorials 2025-02-25 16:52:16 -03:00
Sergio R. Caprile b8d1d7a10b Merge pull request #3049 from cesanta/move
move ESP8266 -> tutorials
2025-02-25 16:11:30 -03:00
Sergio R. Caprile 76769fb4d5 move ESP8266 -> tutorials 2025-02-25 16:10:28 -03:00
Sergio R. Caprile 6ff6f0a4c6 Merge pull request #3048 from cesanta/move
move Arduino examples -> tutorials
2025-02-25 15:52:12 -03:00
Sergio R. Caprile 72a45d2f6a move Arduino examples -> tutorials 2025-02-25 15:48:09 -03:00
Sergio R. Caprile 2fe7c8a410 Merge pull request #3044 from cesanta/eth-drivers-rx
ETH driver: use the same scheme for RX
2025-02-19 14:12:49 -03:00
robert 5269eb9c39 ETH driver: use the same scheme for RX 2025-02-19 10:01:54 -05:00
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 a0d9b6a7e0 fix UB and possible HF trigger 2025-01-28 10:24:59 -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
4005 changed files with 538171 additions and 1021175 deletions

No files matched your search

+1
View File
@@ -0,0 +1 @@
blank_issues_enabled: false
+21
View File
@@ -0,0 +1,21 @@
---
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_
- The result I saw: _provide logs or description_
- My question is: _your question_
# Environment
- mongoose version: _X.Y_
- Compiler/IDE and SDK: ZZZ version _X.Y_
- Target hardware/board: _?_
- Connectivity chip/module: _?_
- Target RTOS/OS (if applicable): _?_
-13
View File
@@ -1,13 +0,0 @@
- My goal is: _describe_
- My actions were: _describe_
- My expectation was: _describe_
- The result I saw: _provide logs or description_
- My question is: _your question_
# Environment
- mongoose version: _X.Y_
- Compiler/IDE and SDK: ZZZ version _X.Y_
- Target hardware/board: _?_
- Connectivity chip/module: _?_
- Target RTOS/OS (if applicable): _?_
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
dry-run: false dry-run: false
language: c++ language: c++
- name: Upload Crash - name: Upload Crash
uses: actions/upload-artifact@v1 uses: actions/upload-artifact@v4
if: env.GO == 1 && failure() && steps.build.outcome == 'success' if: env.GO == 1 && failure() && steps.build.outcome == 'success'
with: with:
name: artifacts name: artifacts
+4 -4
View File
@@ -3,7 +3,7 @@ name: "CodeQL Scanning"
on: on:
schedule: schedule:
- cron: '30 2 * * *' # run at 2:30 AM UTC - cron: '30 23 * * *' # run at 11:30 PM UTC
# Allow manual runs # Allow manual runs
workflow_dispatch: workflow_dispatch:
@@ -17,11 +17,11 @@ jobs:
permissions: permissions:
security-events: write security-events: write
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v3
with: with:
languages: cpp languages: cpp
- run: | - run: |
@@ -29,4 +29,4 @@ jobs:
./test/setup_ga_network.sh && make -C test mip_test CC=gcc ASAN= ASAN_OPTIONS= ./test/setup_ga_network.sh && make -C test mip_test CC=gcc ASAN= ASAN_OPTIONS=
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v3
+20
View File
@@ -0,0 +1,20 @@
name: Fuzz
on:
schedule:
- cron: '0 21 * * *' # run at 9 PM UTC
# Allow manual runs
workflow_dispatch:
env:
CC: clang
jobs:
fuzz:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target: [fuzz, fuzz_tls]
name: ${{ matrix.target }}
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: make -C test ${{ matrix.target }}
+150 -192
View File
@@ -1,7 +1,7 @@
name: Full build and test name: Full build and test
on: on:
schedule: schedule:
- cron: '0 1 * * *' # run at 1 AM UTC - cron: '0 22 * * *' # run at 10 PM UTC
# Allow manual runs # Allow manual runs
workflow_dispatch: workflow_dispatch:
env: env:
@@ -13,7 +13,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
cc: [gcc, clang, g++, clang++] cc: [gcc, clang, g++, clang++]
target: [test, mip_test] target: [test]
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL] ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
select: ["-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1"] select: ["-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=1 -DMG_ENABLE_EPOLL=0", "-DMG_ENABLE_POLL=0 -DMG_ENABLE_EPOLL=1"]
exclude: exclude:
@@ -37,7 +37,23 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: ./test/setup_ga_network.sh && sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }} - run: sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }}
mip:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
cc: [gcc, clang, g++, clang++]
target: [mip_test, mip_tap_test]
ssl: ["", BUILTIN, MBEDTLS, OPENSSL, WOLFSSL]
name: ${{ matrix.target }} CC=${{ matrix.cc }} SSL=${{ matrix.ssl }}
env:
CC: ${{ matrix.cc }}
SSL: ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: if [ "${{ matrix.target }}" == "mip_tap_test" ]; then ./test/setup_ga_network.sh ; fi && sudo apt -y update ; sudo apt -y install libmbedtls-dev libwolfssl-dev && make -C test ${{ matrix.target }} IPV6=0
s390: s390:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@@ -48,7 +64,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390 SSL=${{ matrix.ssl }} - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390 SSL=${{ matrix.ssl }}
armhf: armhf:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@@ -59,7 +75,7 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf SSL=${{ matrix.ssl }} - run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf SSL=${{ matrix.ssl }}
unamalgamated-mg_prefix: unamalgamated-mg_prefix:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
@@ -101,7 +117,7 @@ jobs:
name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }} name: macos SSL=${{ matrix.ssl }} TFLAGS=${{ matrix.select }}
env: env:
SSL: ${{ matrix.ssl }} SSL: ${{ matrix.ssl }}
TFLAGS: ${{ matrix.select }} -DNO_SNTP_CHECK -Wno-sign-conversion # Workaround for MbedTLS 3.5.0 TFLAGS: ${{ matrix.select }} -Wno-sign-conversion # Workaround for MbedTLS 3.5.0
HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_AUTO_UPDATE: 1
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -149,97 +165,12 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: make -C test riscv SSL=${{ matrix.ssl }} - run: make -C test riscv SSL=${{ matrix.ssl }}
examples:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
name: examples ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
- run: sudo apt -y install libpcap-dev
- run: make -C test examples CFLAGS_EXTRA="${{ matrix.ssl }}"
- run: make -C test clean_examples
examples_win:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
name: examples_win ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
# - uses: egor-tensin/setup-mingw@v2
# with:
# platform: x64
- name: test they build
run: make -C test examples_win CFLAGS_EXTRA="${{ matrix.ssl }}"
shell: cmd
- name: test they clean
run: make -C test clean_examples_win
shell: cmd
examples_mac:
runs-on: macos-latest
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
strategy:
fail-fast: false
matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
name: examples_mac ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
- run: make -C test examples_mac CFLAGS_EXTRA="${{ matrix.ssl }}"
- run: make -C test clean_examples_mac
refprojs:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
name: reference-projects ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
- run: make -C test refprojs CFLAGS_EXTRA="${{ matrix.ssl }}"
- run: make -C test clean_refprojs
refprojs_win:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
name: reference-projects_win ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
# - uses: egor-tensin/setup-mingw@v2
# with:
# platform: x64
- name: test they build
run: make -C test refprojs_win CFLAGS_EXTRA="${{ matrix.ssl }}"
shell: cmd
- name: test they clean
run: make -C test clean_refprojs_win
shell: cmd
refprojs_mac:
runs-on: macos-latest
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
strategy:
fail-fast: false
matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
name: reference-projects_mac ${{ matrix.ssl }}
steps:
- uses: actions/checkout@v4
- run: make -C test refprojs CFLAGS_EXTRA="${{ matrix.ssl }}"
- run: make -C test clean_refprojs
tutorials: tutorials:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN] ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
name: tutorials ${{ matrix.ssl }} name: tutorials ${{ matrix.ssl }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -251,7 +182,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN] ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
name: tutorials_win ${{ matrix.ssl }} name: tutorials_win ${{ matrix.ssl }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -270,7 +201,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN] ssl: [-DMG_TLS=MG_TLS_NONE, -DMG_TLS=MG_TLS_BUILTIN]
name: tutorials_mac ${{ matrix.ssl }} name: tutorials_mac ${{ matrix.ssl }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -284,9 +215,67 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: echo # nothing specific to install or do - run: echo # nothing specific to install or do
- run: make -C examples/arduino arduino-xiao - run: make -C test/arduino
# - run: make -C examples/arduino arduino-nano - run: make -C test/arduino cleanall
- 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 tutorials/${{ matrix.example.path }} build
wizard_examples_arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: infineon/xmc47_relax-make-baremetal-builtin
- path: infineon/xmc_plt2go_4400-make-baremetal-builtin
- path: infineon/xmc72_evk-make-baremetal-builtin
- 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 tutorials/${{ matrix.example.path }} build
generic_examples: generic_examples:
@@ -295,18 +284,17 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
example: example:
- path: esp32/uart-bridge - path: micropython/esp32
- path: esp32/micropython - path: http/uart-bridge/esp32
- path: esp8266/http-client-server - path: http/http-client/esp8266/http-client-server
name: ${{ matrix.example.path }} name: ${{ matrix.example.path }}
env: env:
GO: 0 GO: 0
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
- run: echo # nothing specific to install or do - run: echo # nothing specific to install or do
- run: make -C examples/${{ matrix.example.path }} build - run: make -C tutorials/${{ matrix.example.path }} build
generic_examples_arm: generic_examples_arm:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -314,8 +302,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
example: example:
- path: microchip/same54-xpro/mqtt-client - path: mqtt/mqtt-client/microchip/same54-xpro
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos
- path: nxp/nxp-mimxrt1020-azurertos - path: nxp/nxp-mimxrt1020-azurertos
- path: nxp/nxp-frdmk66f-freertos - path: nxp/nxp-frdmk66f-freertos
- path: nxp/nxp-lpcxpresso54s018m-freertos - path: nxp/nxp-lpcxpresso54s018m-freertos
@@ -335,7 +322,7 @@ jobs:
- path: nxp/nxp-lpcxpresso54628-lwip-freertos - path: nxp/nxp-lpcxpresso54628-lwip-freertos
- path: nxp/nxp-twrk65f180m-lwip-freertos - path: nxp/nxp-twrk65f180m-lwip-freertos
- path: nxp/nxp-twrkv58f220m-lwip-freertos - path: nxp/nxp-twrkv58f220m-lwip-freertos
- path: rp2040/pico-rmii - path: pico-sdk/pico-rmii
- path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis - path: stm32/nucleo-f429zi-make-baremetal-builtin-rndis
- path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis - path: stm32/nucleo-f746zg-make-baremetal-builtin-rndis
- path: stm32/nucleo-g031-make-baremetal-builtin - path: stm32/nucleo-g031-make-baremetal-builtin
@@ -346,7 +333,7 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi - run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/${{ matrix.example.path }} build - run: make -C tutorials/${{ matrix.example.path }} build
device_dashboard_examples: device_dashboard_examples:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -354,13 +341,14 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
example: example:
- path: esp32/device-dashboard - path: esp32
name: ${{ matrix.example.path }} name: ${{ matrix.example.path }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: echo # nothing specific to install or do - run: echo # nothing specific to install or do
- run: make -C examples/${{ matrix.example.path }} build - run: make -C tutorials/http/device-dashboard/${{ matrix.example.path }} build
device_dashboard_examples_arm: device_dashboard_examples_arm:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -369,37 +357,22 @@ jobs:
matrix: matrix:
ssl: ["", -DMG_TLS=MG_TLS_BUILTIN] ssl: ["", -DMG_TLS=MG_TLS_BUILTIN]
example: example:
- path: microchip/same54-xpro/device-dashboard - path: tutorials/http/device-dashboard/microchip/same54-xpro
- path: nxp/rt1020-evk-make-baremetal-builtin
- path: nxp/rt1020-evk-make-freertos-builtin - path: nxp/rt1020-evk-make-freertos-builtin
- path: nxp/rt1060-evk-make-baremetal-builtin
- path: nxp/rt1060-evk-make-freertos-builtin - path: nxp/rt1060-evk-make-freertos-builtin
- path: nxp/rt1170-evk-make-baremetal-builtin - path: nxp/rt1170-evk-make-freertos-builtin
- path: renesas/ek-ra6m4-make-baremetal-builtin - path: renesas/ek-ra6m4-make-baremetal-builtin
- path: rp2040/pico-rndis-dashboard - path: pico-sdk/pico-rndis-dashboard
- path: rp2040/pico-w - path: pico-sdk/pico-w-picosdk-freertos-lwip
- path: rp2040/pico-w5500 - path: pico-sdk/pico-2-w-picosdk-freertos-lwip
- path: stm32/nucleo-f429zi-make-baremetal-builtin
- path: stm32/nucleo-f429zi-make-freertos-builtin
- path: stm32/nucleo-f746zg-make-baremetal-builtin
- path: stm32/nucleo-f746zg-make-freertos-builtin
- path: stm32/nucleo-f746zg-make-freertos-tcp - path: stm32/nucleo-f746zg-make-freertos-tcp
- path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver - path: stm32/nucleo-f746zg-make-baremetal-builtin-cmsis_driver
- path: stm32/nucleo-h563zi-make-baremetal-builtin
- path: stm32/nucleo-h563zi-make-freertos-builtin
- path: stm32/nucleo-h723zg-make-freertos-builtin
- path: stm32/nucleo-h743zi-make-baremetal-builtin
- path: stm32/nucleo-h743zi-make-freertos-builtin
- path: stm32/stm32h573i-dk-make-baremetal-builtin
- path: stm32/stm32h573i-dk-make-freertos-builtin
- path: ti/ek-tm4c1294xl-make-baremetal-builtin
- path: ti/ek-tm4c1294xl-make-freertos-builtin
name: ${{ matrix.example.path }} ${{ matrix.ssl }} name: ${{ matrix.example.path }} ${{ matrix.ssl }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi - run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/${{ matrix.example.path }} build CFLAGS_EXTRA="${{ matrix.ssl }}" - run: make -C tutorials/${{ matrix.example.path }} build CFLAGS_EXTRA="${{ matrix.ssl }}"
# mqtt_dashboard_examples: # mqtt_dashboard_examples:
# runs-on: ubuntu-latest # runs-on: ubuntu-latest
@@ -413,7 +386,7 @@ jobs:
# - uses: actions/checkout@v4 # - uses: actions/checkout@v4
# with: { fetch-depth: 2 } # with: { fetch-depth: 2 }
# - run: echo # nothing specific to install or do # - run: echo # nothing specific to install or do
# - run: make -C examples/${{ matrix.example.path }} build # - run: make -C tutorials/${{ matrix.example.path }} build
mqtt_dashboard_examples_arm: mqtt_dashboard_examples_arm:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -421,13 +394,13 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
example: example:
- path: rp2040/pico-rndis-device - path: pico-sdk/pico-rndis-device
name: ${{ matrix.example.path }} name: ${{ matrix.example.path }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi - run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/${{ matrix.example.path }} build - run: make -C tutorials/${{ matrix.example.path }} build
# dual_examples: # dual_examples:
# runs-on: ubuntu-latest # runs-on: ubuntu-latest
@@ -441,30 +414,15 @@ jobs:
# - uses: actions/checkout@v4 # - uses: actions/checkout@v4
# with: { fetch-depth: 2 } # with: { fetch-depth: 2 }
# - run: echo # nothing specific to install or do # - run: echo # nothing specific to install or do
# - run: make -C examples/${{ matrix.example.path }} device_dashboard # - run: make -C tutorials/${{ matrix.example.path }} device_dashboard
# - run: make -C examples/${{ matrix.example.path }} mqtt_dashboard # - run: make -C tutorials/${{ matrix.example.path }} mqtt_dashboard
dual_examples_arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: stm32/nucleo-h723zg-make-baremetal-builtin
name: ${{ matrix.example.path }}
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/${{ matrix.example.path }} device_dashboard
- run: make -C examples/${{ matrix.example.path }} mqtt_dashboard
cube_examples: cube_examples:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: echo # nothing specific to install or do - run: sudo pip install yq
- run: cd test/cube && make - run: cd test/cube && make
zephyr_examples: zephyr_examples:
@@ -473,17 +431,17 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi - run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/zephyr init - run: make -C tutorials/zephyr init REPO=zephyrprojectrtos/ci:v0.26.14 # "no space left on device" with newers
- name: minify manifest - name: minify manifest
uses: mikefarah/yq@master uses: mikefarah/yq@master
with: with:
cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' examples/zephyr/zephyrproject/zephyr/west.yml cmd: yq -i eval '(.manifest.defaults, .manifest.remotes, .manifest.projects[] | select(.name == "cmsis" or .name == "hal_stm32" or .name == "mbedtls" or .name == "mcuboot" or .name == "picolibc" | del(.null) ), .manifest.self) as $i ireduce({};setpath($i | path; $i)) | del(.manifest.projects.[].null) | del(..|select(length==0))' tutorials/zephyr/zephyrproject/zephyr/west.yml
- run: make -C examples/zephyr update - run: make -C tutorials/zephyr update
- run: make -C examples/zephyr/device-dashboard build - run: make -C tutorials/zephyr/device-dashboard build
- run: make -C examples/zephyr/http-client build - run: make -C tutorials/zephyr/http-client build
- run: make -C examples/zephyr/http-server build - run: make -C tutorials/zephyr/http-server build
- run: make -C examples/zephyr/mqtt-aws-client build - run: make -C tutorials/zephyr/mqtt-aws-client build
- run: make -C examples/zephyr/websocket-server build - run: make -C tutorials/zephyr/websocket-server build
test_f7: test_f7:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -492,14 +450,14 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- name: Cube - name: Cube
run: echo # nothing specific to install or do run: echo # nothing specific to install or do
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5 # - run: make -C test/cube test PROJECTS=../../tutorials/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=../../tutorials/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5 - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
test_f4: test_f4:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -508,13 +466,13 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- name: Cube - name: Cube
run: echo # nothing specific to install or do run: echo # nothing specific to install or do
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2 # - run: make -C test/cube test PROJECTS=../../tutorials/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=../../tutorials/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2 - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
test_h743: test_h743:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -523,12 +481,12 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- name: Cube # - name: Cube
run: echo # nothing specific to install or do # run: echo # nothing specific to install or do
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6 # - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
- run: make -C test/cube test PROJECTS=../../examples/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6 # - run: make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
test_h723: test_h723:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -537,8 +495,8 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_h5: test_h5:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -547,8 +505,8 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_rt1020: test_rt1020:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -557,8 +515,8 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_rt1060: test_rt1060:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -567,8 +525,8 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_rt1170: test_rt1170:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -577,8 +535,8 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/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 tutorials/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_ra6m4: test_ra6m4:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -587,8 +545,8 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
# - run: make -C examples/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} # - run: make -C tutorials/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_tm4c: test_tm4c:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -597,8 +555,8 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_same54: test_same54:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -607,8 +565,8 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/microchip/same54-xpro/device-dashboard test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/http/device-dashboard/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
- run: make -C examples/microchip/same54-xpro/mqtt-client test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/mqtt/mqtt-client/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
test_pico_w5500: test_pico_w5500:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -617,5 +575,5 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: SDK - name: SDK
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- run: make -C examples/rp2040/pico-w5500 test VCON_API_KEY=${{secrets.VCON_API_KEY}} - run: make -C tutorials/pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
+241 -301
View File
@@ -25,7 +25,7 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi - run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: ./test/setup_ga_network.sh && make -C test ${{ matrix.target }} run: make -C test ${{ matrix.target }}
s390: s390:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -33,7 +33,7 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi - run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390 run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test s390
armhf: armhf:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -41,7 +41,7 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi - run: if ./test/match_changed_files.sh '^test|^src/.*.[ch]' ; then echo GO=1 >> $GITHUB_ENV ; fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: sudo apt -y update ; sudo apt -y install qemu binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf run: sudo apt -y update ; sudo apt -y install binfmt-support qemu-user-static && docker run --rm --privileged multiarch/qemu-user-static --reset -p yes && make -C test armhf
unamalgamated-mg_prefix: unamalgamated-mg_prefix:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -59,7 +59,7 @@ jobs:
name: macos SSL=${{ matrix.ssl }} name: macos SSL=${{ matrix.ssl }}
env: env:
SSL: ${{ matrix.ssl }} SSL: ${{ matrix.ssl }}
TFLAGS: -DNO_SNTP_CHECK #TFLAGS: -DNO_SNTP_CHECK
HOMEBREW_NO_AUTO_UPDATE: 1 HOMEBREW_NO_AUTO_UPDATE: 1
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
@@ -91,60 +91,6 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- run: make -C test riscv - run: make -C test riscv
examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: make -C test examples_essential
- run: make -C test clean_examples_essential
examples_win:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
# - uses: egor-tensin/setup-mingw@v2
# with:
# platform: x64
- name: test they build
run: make -C test examples_win
shell: cmd
- name: test they clean
run: make -C test clean_examples_win
shell: cmd
examples_mac:
runs-on: macos-latest
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
steps:
- uses: actions/checkout@v4
- run: make -C test examples_mac
- run: make -C test clean_examples_mac
refprojs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: make -C test refprojs
- run: make -C test clean_refprojs
refprojs_win:
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
# - uses: egor-tensin/setup-mingw@v2
# with:
# platform: x64
- name: test they build
run: make -C test refprojs_win
shell: cmd
- name: test they clean
run: make -C test clean_refprojs_win
shell: cmd
refprojs_mac:
runs-on: macos-latest
env: { HOMEBREW_NO_AUTO_UPDATE: 1 }
steps:
- uses: actions/checkout@v4
- run: make -C test refprojs
- run: make -C test clean_refprojs
tutorials: tutorials:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
@@ -173,92 +119,52 @@ jobs:
- run: make -C test clean_tutorials_mac - run: make -C test clean_tutorials_mac
generic_examples: # wizard_examples:
runs-on: ubuntu-latest # runs-on: ubuntu-latest
strategy: # strategy:
fail-fast: false # fail-fast: false
matrix: # matrix:
example: # example:
- path: esp32/uart-bridge # - path: esp32/esp32-idf
- path: esp8266/http-client-server # name: ${{ matrix.example.path }}
name: ${{ matrix.example.path }} # env:
env: # GO: 0
GO: 0 # steps:
steps: # - uses: actions/checkout@v4
- uses: actions/checkout@v4 # with: { fetch-depth: 2 }
with: { fetch-depth: 2 } # - run: |
- run: if ./test/match_changed_files.sh '^src|^examples/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi # if ./test/match_changed_files.sh '^src'; then
- if: ${{ env.GO == 1 }} # echo GO=1 >> $GITHUB_ENV
run: | # # nothing specific to install or do
# nothing specific to install or do # fi
- if: ${{ env.GO == 1 }} # - if: ${{ env.GO == 1 }}
run: make -C examples/${{ matrix.example.path }} build # run: make -C tutorials/${{ matrix.example.path }} build
generic_examples_arm: wizard_examples_arm:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
example: example:
- path: infineon/infineon-xmc4700_4800-lwip-rtx-rtos - path: infineon/xmc47_relax-make-baremetal-builtin
- path: stm32/nucleo-g031-make-baremetal-builtin - path: infineon/xmc_plt2go_4400-make-baremetal-builtin
name: ${{ matrix.example.path }} - path: infineon/xmc72_evk-make-baremetal-builtin
env: - path: nxp/frdm-mcxn947-make-baremetal-builtin
GO: 0 - path: nxp/frdm-mcxn947-make-freertos-builtin
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
- if: ${{ env.GO == 1 }}
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- if: ${{ env.GO == 1 }}
run: make -C examples/${{ matrix.example.path }} build
device_dashboard_examples:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: esp32/device-dashboard
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/${{ matrix.example.path }}'; 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
device_dashboard_examples_arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: microchip/same54-xpro/device-dashboard
- path: nxp/rt1020-evk-make-baremetal-builtin - 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-baremetal-builtin
- path: nxp/rt1060-evk-make-freertos-builtin
- path: nxp/rt1170-evk-make-baremetal-builtin - path: nxp/rt1170-evk-make-baremetal-builtin
- path: renesas/ek-ra6m4-make-baremetal-builtin - path: pico-sdk/pico-w-picosdk-baremetal-builtin
- path: rp2040/pico-rndis-dashboard - path: pico-sdk/pico-2-w-picosdk-baremetal-builtin
- path: rp2040/pico-w - path: pico-sdk/w5500-evb-pico-picosdk-baremetal-builtin
- path: rp2040/pico-w5500 - path: pico-sdk/w5500-evb-pico2-picosdk-baremetal-builtin
- path: stm32/nucleo-f429zi-make-baremetal-builtin - path: stm32/nucleo-f429zi-make-baremetal-builtin
- path: stm32/nucleo-f429zi-make-freertos-builtin - path: stm32/nucleo-f429zi-make-freertos-builtin
- path: stm32/nucleo-f746zg-make-baremetal-builtin - path: stm32/nucleo-f746zg-make-baremetal-builtin
- path: stm32/nucleo-f746zg-make-freertos-builtin - path: stm32/nucleo-f746zg-make-freertos-builtin
- 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-baremetal-builtin
- path: stm32/nucleo-h563zi-make-freertos-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-h723zg-make-freertos-builtin
- path: stm32/nucleo-h743zi-make-baremetal-builtin - path: stm32/nucleo-h743zi-make-baremetal-builtin
- path: stm32/nucleo-h743zi-make-freertos-builtin - path: stm32/nucleo-h743zi-make-freertos-builtin
@@ -273,12 +179,104 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: | - run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then if ./test/match_changed_files.sh '^src'; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: make -C examples/${{ matrix.example.path }} build run: make -C tutorials/${{ matrix.example.path }} build
generic_examples:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: http/uart-bridge/esp32
- path: http/http-client/esp8266/http-client-server
name: ${{ matrix.example.path }}
env:
GO: 0
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: if ./test/match_changed_files.sh '^src|^tutorials/http/uart-bridge|^tutorials/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
- if: ${{ env.GO == 1 }}
run: |
# nothing specific to install or do
- if: ${{ env.GO == 1 }}
run: make -C tutorials/${{ matrix.example.path }} build
generic_examples_arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: stm32/nucleo-g031-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|^tutorials/${{ matrix.example.path }}'; then echo GO=1 >> $GITHUB_ENV ; fi
- if: ${{ env.GO == 1 }}
run: sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
- if: ${{ env.GO == 1 }}
run: make -C tutorials/${{ matrix.example.path }} build
device_dashboard_examples:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: esp32
name: ${{ matrix.example.path }}
env:
GO: 0
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: |
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard'; then
echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do
fi
- if: ${{ env.GO == 1 }}
run: make -C tutorials/http/device-dashboard/${{ matrix.example.path }} build
device_dashboard_examples_arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: http/device-dashboard/microchip/same54-xpro
- path: nxp/rt1020-evk-make-freertos-builtin
- path: nxp/rt1060-evk-make-freertos-builtin
- path: nxp/rt1170-evk-make-freertos-builtin
- path: renesas/ek-ra6m4-make-baremetal-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
name: ${{ matrix.example.path }}
env:
GO: 0
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: |
if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|^tutorials/${{ 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: make -C tutorials/${{ matrix.example.path }} build
# mqtt_dashboard_examples: # mqtt_dashboard_examples:
# runs-on: ubuntu-latest # runs-on: ubuntu-latest
@@ -294,12 +292,12 @@ jobs:
# - uses: actions/checkout@v4 # - uses: actions/checkout@v4
# with: { fetch-depth: 2 } # with: { fetch-depth: 2 }
# - run: | # - run: |
# if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then # if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-dashboard/device|^tutorials/${{ matrix.example.path }}'; then
# echo GO=1 >> $GITHUB_ENV # echo GO=1 >> $GITHUB_ENV
# # nothing specific to install or do # # nothing specific to install or do
# fi # fi
# - if: ${{ env.GO == 1 }} # - if: ${{ env.GO == 1 }}
# run: make -C examples/${{ matrix.example.path }} build # run: make -C tutorials/${{ matrix.example.path }} build
mqtt_dashboard_examples_arm: mqtt_dashboard_examples_arm:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -307,7 +305,7 @@ jobs:
fail-fast: false fail-fast: false
matrix: matrix:
example: example:
- path: rp2040/pico-rndis-device - path: pico-sdk/pico-rndis-device
name: ${{ matrix.example.path }} name: ${{ matrix.example.path }}
env: env:
GO: 0 GO: 0
@@ -315,70 +313,12 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: | - run: |
if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-dashboard/device|^tutorials/${{ matrix.example.path }}'; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: make -C examples/${{ matrix.example.path }} build run: make -C tutorials/${{ matrix.example.path }} build
# dual_examples:
# runs-on: ubuntu-latest
# strategy:
# fail-fast: false
# matrix:
# example:
# - path:
# name: ${{ matrix.example.path }}
# env:
# GO: 0
# steps:
# - uses: actions/checkout@v4
# with: { fetch-depth: 2 }
# - run: |
# if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
# echo GO=1 >> $GITHUB_ENV
# # nothing specific to install or do
# fi
# - if: ${{ env.GO == 1 }}
# run: |
# if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
# make -C examples/${{ matrix.example.path }} device_dashboard
# fi
# - if: ${{ env.GO == 1 }}
# run: |
# if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
# make -C examples/${{ matrix.example.path }} mqtt_dashboard
# fi
dual_examples_arm:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
example:
- path: stm32/nucleo-h723zg-make-baremetal-builtin
name: ${{ matrix.example.path }}
env:
GO: 0
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 2 }
- run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi
- if: ${{ env.GO == 1 }}
run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|^examples/${{ matrix.example.path }}'; then
make -C examples/${{ matrix.example.path }} device_dashboard
fi
- if: ${{ env.GO == 1 }}
run: |
if ./test/match_changed_files.sh '^src|examples/mqtt-dashboard/device|^examples/${{ matrix.example.path }}'; then
make -C examples/${{ matrix.example.path }} mqtt_dashboard
fi
cube_examples: cube_examples:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -388,9 +328,9 @@ jobs:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- run: | - run: |
if ./test/match_changed_files.sh '^src|examples/stm32/nucleo-*-cube-*'; then if ./test/match_changed_files.sh '^src|tutorials/stm32/nucleo-*-cube-*'; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do sudo pip install yq
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: cd test/cube && make run: cd test/cube && make
@@ -404,7 +344,7 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32|examples/nxp|examples/ti|examples/microchip/same" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f7.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
@@ -412,40 +352,40 @@ jobs:
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true # continue so next test has a chance to re-flash and exit from collisions and flash failures continue-on-error: true # continue so next test has a chance to re-flash and exit from collisions and flash failures
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f746zg-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f746zg-make-baremetal-builtin'; then
make -C examples/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-f746zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-make-freertos-builtin'; then
make -C examples/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-f746zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-make-freertos-tcp'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-make-freertos-tcp'; then
make -C examples/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-f746zg-make-freertos-tcp test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- name: Cube - name: Cube
run: | run: |
echo GO=0 >> $GITHUB_ENV echo GO=0 >> $GITHUB_ENV
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f7.*-cube-'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f7.*-cube-'; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do # nothing specific to install or do
fi fi
# - if: ${{ env.GO == 1 }}
# run: |
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-baremetal-builtin'; then
# make -C test/cube test PROJECTS=../../tutorials/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 'tutorials/stm32/nucleo-f746zg-cube-freertos-builtin'; then
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
# fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f746zg-cube-baremetal-builtin'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f746zg-cube-freertos-lwip'; then
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5 make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f746zg-cube-freertos-lwip 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
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f746zg-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=5
fi fi
@@ -458,42 +398,42 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-f4.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f4.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-f429zi-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-f429zi-make-baremetal-builtin'; then
make -C examples/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-f429zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-make-freertos-builtin'; then
make -C examples/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-f429zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- name: Cube - name: Cube
run: | run: |
echo GO=0 >> $GITHUB_ENV echo GO=0 >> $GITHUB_ENV
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f4.*-cube-'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f4.*-cube-'; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
# nothing specific to install or do # nothing specific to install or do
fi fi
# - if: ${{ env.GO == 1 }}
# run: |
# if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-baremetal-builtin'; then
# make -C test/cube test PROJECTS=../../tutorials/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 'tutorials/stm32/nucleo-f429zi-cube-freertos-builtin'; then
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
# fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-f429zi-cube-baremetal-builtin'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-f429zi-cube-freertos-lwip'; then
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-baremetal-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2 make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-f429zi-cube-freertos-lwip 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
make -C test/cube test PROJECTS=../../examples/stm32/nucleo-f429zi-cube-freertos-lwip VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=2
fi fi
test_h743: test_h743:
@@ -505,38 +445,38 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h74.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h74.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h743zi-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h743zi-make-baremetal-builtin'; then
make -C examples/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-h743zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h743zi-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h743zi-make-freertos-builtin'; then
make -C examples/stm32/nucleo-h743zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/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 fi
# - name: Cube
# run: |
# echo GO=0 >> $GITHUB_ENV
# if ./test/match_changed_files.sh 'tutorials/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 'tutorials/stm32/nucleo-h743zi-cube-baremetal-builtin'; then
# make -C test/cube test PROJECTS=../../tutorials/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 'tutorials/stm32/nucleo-h743zi-cube-freertos-builtin'; then
# make -C test/cube test PROJECTS=../../tutorials/stm32/nucleo-h743zi-cube-freertos-builtin VCON_API_KEY=${{secrets.VCON_API_KEY}} DEVICE=6
# fi
test_h723: test_h723:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -547,20 +487,20 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h72.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h72.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h723zg-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h723zg-make-baremetal-builtin'; then
make -C examples/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-h723zg-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h723zg-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h723zg-make-freertos-builtin'; then
make -C examples/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-h723zg-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
test_h5: test_h5:
@@ -572,20 +512,20 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/stm32/nucleo-h5.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h5.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/stm32/nucleo-h563zi-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/stm32/nucleo-h563zi-make-baremetal-builtin'; then
make -C examples/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-h563zi-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/stm32/nucleo-h563zi-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/stm32/nucleo-h563zi-make-freertos-builtin'; then
make -C examples/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/stm32/nucleo-h563zi-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
test_rt1020: test_rt1020:
@@ -597,20 +537,20 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1020.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1020.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1020-evk-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1020-evk-make-baremetal-builtin'; then
make -C examples/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/nxp/rt1020-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/nxp/rt1020-evk-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/nxp/rt1020-evk-make-freertos-builtin'; then
make -C examples/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/nxp/rt1020-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
test_rt1060: test_rt1060:
@@ -622,20 +562,20 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1060.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1060.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1060-evk-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1060-evk-make-baremetal-builtin'; then
make -C examples/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/nxp/rt1060-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/nxp/rt1060-evk-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/nxp/rt1060-evk-make-freertos-builtin'; then
make -C examples/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/nxp/rt1060-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
test_rt1170: test_rt1170:
@@ -647,21 +587,21 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/nxp/rt1170.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/nxp/rt1170.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/nxp/rt1170-evk-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/nxp/rt1170-evk-make-baremetal-builtin'; then
make -C examples/nxp/rt1170-evk-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/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 'tutorials/nxp/rt1170-evk-make-freertos-builtin'; then
make -C tutorials/nxp/rt1170-evk-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi 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: test_ra6m4:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -672,20 +612,20 @@ jobs:
with: { fetch-depth: 3 } with: { fetch-depth: 3 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/renesas/ek-ra6m4.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/renesas/ek-ra6m4.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
continue-on-error: true continue-on-error: true
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/renesas/ek-ra6m4-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/renesas/ek-ra6m4-make-baremetal-builtin'; then
make -C examples/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/renesas/ek-ra6m4-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
# - if: ${{ env.GO == 1 }} # - if: ${{ env.GO == 1 }}
# run: | # run: |
# if ./test/match_changed_files.sh 'examples/renesas/ek-ra6m4-make-freertos-builtin'; then # if ./test/match_changed_files.sh 'tutorials/renesas/ek-ra6m4-make-freertos-builtin'; then
# make -C examples/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} # make -C tutorials/renesas/ek-ra6m4-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
# fi # fi
test_tm4c: test_tm4c:
@@ -697,19 +637,19 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/ti/ek-tm4c.*-make-" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/ti/ek-tm4c.*-make-" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/ti/ek-tm4c1294xl-make-baremetal-builtin'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard|tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin'; then
make -C examples/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/ti/ek-tm4c1294xl-make-baremetal-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/ti/ek-tm4c1294xl-make-freertos-builtin'; then if ./test/match_changed_files.sh 'tutorials/ti/ek-tm4c1294xl-make-freertos-builtin'; then
make -C examples/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/ti/ek-tm4c1294xl-make-freertos-builtin test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
test_same54: test_same54:
@@ -721,19 +661,19 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: baremetal - name: baremetal
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/microchip/same54-xpro" ; then if ./test/match_changed_files.sh "^src|tutorials/http/device-dashboard|tutorials/mqtt/mqtt-client" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh '^src|examples/device-dashboard|examples/microchip/same54-xpro/device-dashboard'; then if ./test/match_changed_files.sh '^src|tutorials/http/device-dashboard'; then
make -C examples/microchip/same54-xpro/device-dashboard test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/http/device-dashboard/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: | run: |
if ./test/match_changed_files.sh 'examples/microchip/same54-xpro/mqtt-client'; then if ./test/match_changed_files.sh '^src|tutorials/mqtt/mqtt-client'; then
make -C examples/microchip/same54-xpro/mqtt-client test VCON_API_KEY=${{secrets.VCON_API_KEY}} make -C tutorials/mqtt/mqtt-client/microchip/same54-xpro test VCON_API_KEY=${{secrets.VCON_API_KEY}}
fi fi
test_pico_w5500: test_pico_w5500:
@@ -745,10 +685,10 @@ jobs:
with: { fetch-depth: 2 } with: { fetch-depth: 2 }
- name: SDK - name: SDK
run: | run: |
if ./test/match_changed_files.sh "^src|examples/device-dashboard|examples/rp2040/pico-w5500" ; then if ./test/match_changed_files.sh "^src" ; then
echo GO=1 >> $GITHUB_ENV echo GO=1 >> $GITHUB_ENV
sudo apt -y update && sudo apt -y install gcc-arm-none-eabi sudo apt -y update && sudo apt -y install gcc-arm-none-eabi
fi fi
- if: ${{ env.GO == 1 }} - if: ${{ env.GO == 1 }}
run: make -C examples/rp2040/pico-w5500 test VCON_API_KEY=${{secrets.VCON_API_KEY}} run: make -C tutorials/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) 2004-2013 Sergey Lyubka
Copyright (c) 2013-2024 Cesanta Software Limited Copyright (c) 2013-2025 Cesanta Software Limited
All rights reserved All rights reserved
This software is dual-licensed: you can redistribute it and/or modify This software is dual-licensed: you can redistribute it and/or modify
+11 -2
View File
@@ -4,6 +4,7 @@
[![Build Status]( https://github.com/cesanta/mongoose/workflows/build/badge.svg)](https://github.com/cesanta/mongoose/actions) [![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) [![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) [![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 Mongoose is a network library for C/C++. It provides event-driven non-blocking
APIs for TCP, UDP, HTTP, WebSocket, MQTT, and other protocols. It is designed APIs for TCP, UDP, HTTP, WebSocket, MQTT, and other protocols. It is designed
@@ -14,7 +15,7 @@ robust, and easy. Features include:
- Cross-platform: - Cross-platform:
- works on Linux/UNIX, MacOS, Windows, Android - works on Linux/UNIX, MacOS, Windows, Android
- works on STM32, NXP, ESP32, NRF52, TI, Microchip, and other - works on ST, NXP, ESP32, Nordic, TI, Microchip, Infineon, Renesas and other chips
- write code once - and it'll work everywhere - write code once - and it'll work everywhere
- ideal for the unification of the network infrastructure code across company - ideal for the unification of the network infrastructure code across company
- Built-in protocols: plain TCP/UDP, SNTP, HTTP, MQTT, Websocket, and other - Built-in protocols: plain TCP/UDP, SNTP, HTTP, MQTT, Websocket, and other
@@ -70,7 +71,7 @@ HTTP server implements a REST API that returns current time. JSON formatting:
static void ev_handler(struct mg_connection *c, int ev, void *ev_data) { static void ev_handler(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_HTTP_MSG) { if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data; struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_http_match_uri(hm, "/api/time/get")) { if (mg_match(hm->uri, mg_str("/api/time/get"), NULL)) {
mg_http_reply(c, 200, "", "{%m:%lu}\n", MG_ESC("time"), time(NULL)); mg_http_reply(c, 200, "", "{%m:%lu}\n", MG_ESC("time"), time(NULL));
} else { } else {
mg_http_reply(c, 500, "", "{%m:%m}\n", MG_ESC("error"), MG_ESC("Unsupported URI")); mg_http_reply(c, 500, "", "{%m:%m}\n", MG_ESC("error"), MG_ESC("Unsupported URI"));
@@ -170,6 +171,14 @@ We take security seriously:
of which we get notified and in case of any issue, act similar to (3). of which we get notified and in case of any issue, act similar to (3).
## Articles
Technical guides and deep dives into embedded web servers, WebUI integration and embedded networking technologies:
- [Embedded Web Server: A Comprehensive Guide for Modern Connected Devices](https://mongoose.ws/articles/embedded-web-server-a-comprehensive-guide-for-modern-connected-devices/)
- [Building Embedded Web Device Dashboards](https://mongoose.ws/articles/building-embedded-web-device-dashboard/)
- [ESP32 Device Dashboard: A Step-by-Step Guide for Developers](https://mongoose.ws/articles/esp32-device-dashboard/)
## Contributions ## Contributions
Contributions are welcome! Please follow the guidelines below: Contributions are welcome! Please follow the guidelines below:
-24
View File
@@ -1,24 +0,0 @@
# Mongoose Network Library Examples
In order to build and run any of the existing examples, please follow:
https://mongoose.ws/documentation/#how-to-build-and-run-examples
## Contributing
Rules for creating a new example:
- Makefile golden reference for desktop/server example: [http-server](http-server)
- Makefile golden reference for the embedded example:
[stm32/nucleo-f746zg-baremetal](stm32/nucleo-f746zg-baremetal)
- An example must build on Windows, Mac and Ubuntu Linux systems
- Assume that user installed tools according to https://mongoose.ws/tutorials/tools/
- Makefile must not include any other make files
- Use `CFLAGS` for system-specific compilation options
- Use `CFLAGS_MONGOOSE` for mongoose-specific compilation options
- Use `$(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA)` to compile
- If external repository is required, download it on demand using git
shallow clone. See embedded example golden reference
- Keep Makefile as short as possible, but verbose to understand it easily
- Symlink files when required, like `mongoose.c`, `ca.pem`, etc. Make no copies
- Example's README.md should contain only the title and the link to mongoose.ws
tutorial page
-28
View File
@@ -1,28 +0,0 @@
all:
example:
true
arduino: ENV = -v $(CWD):/root
arduino:
curl -sL http://downloads.arduino.cc/arduino-1.8.19-linux64.tar.xz | unxz | tar -xf -
mv arduino-* $@
arduino-xiao-board:
./arduino/arduino --pref "boardsmanager.additional.urls=https://files.seeedstudio.com/arduino/package_seeeduino_boards_index.json" --save-prefs
./arduino/arduino --pref "compiler.warning_level=all" --save-prefs
./arduino/arduino --install-boards Seeeduino:samd
arduino-xiao: arduino arduino-xiao-board
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
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
clean:
rm -rf arduino
cleanall: clean #otherwise some parts of xiao-board installation will fail as already installed
rm -rf ~/.arduino15 ~/.oracle_jre_usage
@@ -1,16 +0,0 @@
#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_W5500 1
#define mkdir(a, b) (-1)
#define MG_IO_SIZE 128
//#define MG_ENABLE_LOG 0
@@ -1,49 +0,0 @@
#include <SPI.h>
#include "mongoose.h"
#define SS_PIN 3 // Slave select pin
struct mg_mgr mgr; // Mongoose event manager
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
};
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // network interface
void setup() {
Serial.begin(115200);
pinMode(SS_PIN, OUTPUT);
SPI.begin();
// Set logging function to a serial print
mg_log_set_fn([](char ch, void *) { Serial.print(ch); }, NULL);
mg_mgr_init(&mgr);
delay(3000);
MG_INFO(("Starting 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);
}
void loop() {
mg_mgr_poll(&mgr, 1);
}
@@ -1,16 +0,0 @@
#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_W5500 1
#define mkdir(a, b) (-1)
#define MG_IO_SIZE 512
//#define MG_ENABLE_LOG 0
-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
@@ -1,51 +0,0 @@
#include <SPI.h>
#include "net.h"
#define SS_PIN 17 // Slave select pin
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
};
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);
}
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 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();
}
void loop() {
if (Serial.available()) process_input(Serial.read());
mg_mgr_poll(&mgr, 1);
}
-56
View File
@@ -1,56 +0,0 @@
PROG ?= ./example # Program we are building
PACK ?= ./pack # Packing executable
DELETE = rm -rf # Command to remove files
GZIP ?= gzip # For compressing files in web_root/
OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c net.c packed_fs.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
NPX ?= npx
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
CFLAGS_MONGOOSE += -DMG_ENABLE_PACKED_FS=1
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
PROG = example.exe # Use .exe suffix for the binary
PACK = pack.exe # Packing executable
CC = gcc # Use MinGW gcc compiler
CFLAGS += -lws2_32 # Link against Winsock library
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
GZIP = echo # No gzip on Windows
endif
# Default target. Build and run program
all: $(PROG)
$(RUN) $(PROG) $(ARGS)
# Build program from sources
$(PROG): $(SOURCES)
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
# Bundle JS libraries (preact, preact-router, ...) into a single file
web_root/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
web_root/main.css: web_root/index.html $(wildcard web_root/*.js)
$(NPX) tailwindcss -o $@ --minify
# Generate packed filesystem for serving Web UI
packed_fs.c: $(wildcard web_root/*) $(wildcard certs/*) Makefile web_root/main.css web_root/bundle.js
$(GZIP) web_root/*
$(CC) ../../test/pack.c -o $(PACK)
$(PACK) web_root/* certs/* > $@
$(GZIP) -d web_root/*
mbedtls:
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
$(PROG): mbedtls
endif
# Cleanup. Delete built program and all build artifacts
clean:
$(DELETE) $(PROG) $(PACK) *.o *.obj *.exe *.dSYM mbedtls
-1
View File
@@ -1 +0,0 @@
../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../mongoose.h
-327
View File
@@ -1,327 +0,0 @@
// Copyright (c) 2023 Cesanta Software Limited
// All rights reserved
#include "net.h"
// Authenticated user.
// A user can be authenticated by:
// - a name:pass pair, passed in a header Authorization: Basic .....
// - an access_token, passed in a header Cookie: access_token=....
// When a user is shown a login screen, she enters a user:pass. If successful,
// a server responds with a http-only access_token cookie set.
struct user {
const char *name, *pass, *access_token;
};
// Settings
struct settings {
bool log_enabled;
int log_level;
long brightness;
char *device_name;
};
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;
srand((unsigned) no);
e->type = (uint8_t) rand() % 4;
e->prio = (uint8_t) rand() % 3;
e->timestamp =
(unsigned long) ((int64_t) mg_now() - 86400 * 1000 /* one day back */ +
no * 300 * 1000 /* 5 mins between alerts */ +
1000 * (rand() % 300) /* randomize event time */) /
1000UL;
mg_snprintf(e->text, MAX_EVENT_TEXT_SIZE, "event#%d", no);
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);
}
// Parse HTTP requests, return authenticated user or NULL
static struct user *authenticate(struct mg_http_message *hm) {
// In production, make passwords strong and tokens randomly generated
// In this example, user list is kept in RAM. In production, it can
// be backed by file, database, or some other method.
static struct user users[] = {
{"admin", "admin", "admin_token"},
{"user1", "user1", "user1_token"},
{"user2", "user2", "user2_token"},
{NULL, NULL, NULL},
};
char user[64], pass[64];
struct user *u, *result = NULL;
mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
MG_VERBOSE(("user [%s] pass [%s]", user, pass));
if (user[0] != '\0' && pass[0] != '\0') {
// Both user and password is set, search by user/password
for (u = users; result == NULL && u->name != NULL; u++)
if (strcmp(user, u->name) == 0 && strcmp(pass, u->pass) == 0) result = u;
} else if (user[0] == '\0') {
// Only password is set, search by token
for (u = users; result == NULL && u->name != NULL; u++)
if (strcmp(pass, u->access_token) == 0) result = u;
}
return result;
}
static void handle_login(struct mg_connection *c, struct user *u) {
char cookie[256];
mg_snprintf(cookie, sizeof(cookie),
"Set-Cookie: access_token=%s; Path=/; "
"%sHttpOnly; SameSite=Lax; Max-Age=%d\r\n",
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];
mg_snprintf(cookie, sizeof(cookie),
"Set-Cookie: access_token=; Path=/; "
"Expires=Thu, 01 Jan 1970 00:00:00 UTC; "
"%sHttpOnly; Max-Age=0; \r\n",
c->is_tls ? "Secure; " : "");
mg_http_reply(c, 200, cookie, "true\n");
}
static void handle_debug(struct mg_connection *c, struct mg_http_message *hm) {
int level = mg_json_get_long(hm->body, "$.level", MG_LL_DEBUG);
mg_log_set(level);
mg_http_reply(c, 200, "", "Debug level set to %d\n", level);
}
static size_t print_int_arr(void (*out)(char, void *), void *ptr, va_list *ap) {
size_t i, len = 0, num = va_arg(*ap, size_t); // Number of items in the array
int *arr = va_arg(*ap, int *); // Array ptr
for (i = 0; i < num; i++) {
len += mg_xprintf(out, ptr, "%s%d", i == 0 ? "" : ",", arr[i]);
}
return len;
}
static void handle_stats_get(struct mg_connection *c) {
int points[] = {21, 22, 22, 19, 18, 20, 23, 23, 22, 22, 22, 23, 22};
mg_http_reply(c, 200, s_json_header, "{%m:%d,%m:%d,%m:[%M]}\n",
MG_ESC("temperature"), 21, //
MG_ESC("humidity"), 67, //
MG_ESC("points"), print_int_arr,
sizeof(points) / sizeof(points[0]), points);
}
static size_t print_events(void (*out)(char, void *), void *ptr, va_list *ap) {
size_t len = 0;
struct ui_event ev;
int pageno = va_arg(*ap, int);
int no = (pageno - 1) * EVENTS_PER_PAGE;
int end = no + EVENTS_PER_PAGE;
while ((no = ui_event_next(no, &ev)) != 0 && no <= end) {
len += mg_xprintf(out, ptr, "%s{%m:%lu,%m:%d,%m:%d,%m:%m}\n", //
len == 0 ? "" : ",", //
MG_ESC("time"), ev.timestamp, //
MG_ESC("type"), ev.type, //
MG_ESC("prio"), ev.prio, //
MG_ESC("text"), MG_ESC(ev.text));
}
return len;
}
static void handle_events_get(struct mg_connection *c,
struct mg_http_message *hm) {
int pageno = mg_json_get_long(hm->body, "$.page", 1);
mg_http_reply(c, 200, s_json_header, "{%m:[%M], %m:%d}\n", MG_ESC("arr"),
print_events, pageno, MG_ESC("totalCount"), MAX_EVENTS_NO);
}
static void handle_settings_set(struct mg_connection *c, struct mg_str body) {
struct settings settings;
char *s = mg_json_get_str(body, "$.device_name");
bool ok = true;
memset(&settings, 0, sizeof(settings));
mg_json_get_bool(body, "$.log_enabled", &settings.log_enabled);
settings.log_level = mg_json_get_long(body, "$.log_level", 0);
settings.brightness = mg_json_get_long(body, "$.brightness", 0);
if (s && strlen(s) < MAX_DEVICE_NAME) {
free(settings.device_name);
settings.device_name = s;
} else {
free(s);
}
s_settings = settings; // Save to the device flash
mg_http_reply(c, 200, s_json_header,
"{%m:%s,%m:%m}", //
MG_ESC("status"), ok ? "true" : "false", //
MG_ESC("message"), MG_ESC(ok ? "Success" : "Failed"));
}
static void handle_settings_get(struct mg_connection *c) {
mg_http_reply(c, 200, s_json_header, "{%m:%s,%m:%hhu,%m:%hhu,%m:%m}\n", //
MG_ESC("log_enabled"),
s_settings.log_enabled ? "true" : "false", //
MG_ESC("log_level"), s_settings.log_level, //
MG_ESC("brightness"), s_settings.brightness, //
MG_ESC("device_name"), MG_ESC(s_settings.device_name));
}
static void handle_firmware_upload(struct mg_connection *c,
struct mg_http_message *hm) {
char name[64], offset[20], total[20];
struct mg_str data = hm->body;
long ofs = -1, tot = -1;
name[0] = offset[0] = '\0';
mg_http_get_var(&hm->query, "name", name, sizeof(name));
mg_http_get_var(&hm->query, "offset", offset, sizeof(offset));
mg_http_get_var(&hm->query, "total", total, sizeof(total));
MG_INFO(("File %s, offset %s, len %lu", name, offset, data.len));
if ((ofs = mg_json_get_long(mg_str(offset), "$", -1)) < 0 ||
(tot = mg_json_get_long(mg_str(total), "$", -1)) < 0) {
mg_http_reply(c, 500, "", "offset and total not set\n");
} else if (ofs == 0 && mg_ota_begin((size_t) tot) == false) {
mg_http_reply(c, 500, "", "mg_ota_begin(%ld) failed\n", tot);
} else if (data.len > 0 && mg_ota_write(data.buf, data.len) == false) {
mg_http_reply(c, 500, "", "mg_ota_write(%lu) @%ld failed\n", data.len, ofs);
mg_ota_end();
} else if (data.len == 0 && mg_ota_end() == false) {
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) {
if (c->fn_data != NULL) { // TLS listener!
struct mg_tls_opts opts = {0};
opts.cert = mg_unpacked("/certs/server_cert.pem");
opts.key = mg_unpacked("/certs/server_key.pem");
mg_tls_init(c, &opts);
}
} else if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
struct user *u = authenticate(hm);
if (mg_match(hm->uri, mg_str("/api/#"), NULL) && u == NULL) {
mg_http_reply(c, 403, "", "Not Authorised\n");
} else if (mg_match(hm->uri, mg_str("/api/login"), NULL)) {
handle_login(c, u);
} else if (mg_match(hm->uri, mg_str("/api/logout"), NULL)) {
handle_logout(c);
} else if (mg_match(hm->uri, mg_str("/api/debug"), NULL)) {
handle_debug(c, hm);
} else if (mg_match(hm->uri, mg_str("/api/stats/get"), NULL)) {
handle_stats_get(c);
} else if (mg_match(hm->uri, mg_str("/api/events/get"), NULL)) {
handle_events_get(c, hm);
} else if (mg_match(hm->uri, mg_str("/api/settings/get"), NULL)) {
handle_settings_get(c);
} else if (mg_match(hm->uri, mg_str("/api/settings/set"), NULL)) {
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));
#if MG_ARCH == MG_ARCH_UNIX || MG_ARCH == MG_ARCH_WIN32
opts.root_dir = "web_root"; // On workstations, use filesystem
#else
opts.root_dir = "/web_root"; // On embedded, use packed files
opts.fs = &mg_fs_packed;
#endif
mg_http_serve_dir(c, ev_data, &opts);
}
MG_DEBUG(("%lu %.*s %.*s -> %.*s", c->id, (int) hm->method.len,
hm->method.buf, (int) hm->uri.len, hm->uri.buf, (int) 3,
&c->send.buf[9]));
}
}
void web_init(struct mg_mgr *mgr) {
s_settings.device_name = strdup("My Device");
mg_http_listen(mgr, HTTP_URL, fn, NULL);
mg_http_listen(mgr, HTTPS_URL, fn, (void *) 1);
mg_timer_add(mgr, 3600 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT,
timer_sntp_fn, mgr);
}
File diff suppressed because it is too large. Load diff
@@ -1 +0,0 @@
/*! tailwindcss v3.3.2 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter var,Helvetica,sans-serif;font-feature-settings:"cv11","ss01";font-variation-settings:"opsz" 32}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,::backdrop,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.bottom-0{bottom:0}.left-0{left:0}.right-auto{right:auto}.top-0{top:0}.isolate{isolation:isolate}.z-10{z-index:10}.z-\[48\]{z-index:48}.z-\[60\]{z-index:60}.col-span-2{grid-column:span 2/span 2}.m-4{margin:1rem}.mx-auto{margin-left:auto;margin-right:auto}.my-0{margin-top:0;margin-bottom:0}.my-1{margin-top:.25rem;margin-bottom:.25rem}.my-2{margin-top:.5rem;margin-bottom:.5rem}.my-3{margin-top:.75rem;margin-bottom:.75rem}.my-4{margin-top:1rem;margin-bottom:1rem}.my-5{margin-top:1.25rem;margin-bottom:1.25rem}.mb-1{margin-bottom:.25rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-2{margin-right:.5rem}.mr-4{margin-right:1rem}.mt-1{margin-top:.25rem}.mt-3{margin-top:.75rem}.mt-5{margin-top:1.25rem}.mt-7{margin-top:1.75rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-full{height:100%}.min-h-screen{min-height:100vh}.w-0{width:0}.w-11{width:2.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-72{width:18rem}.w-96{width:24rem}.w-full{width:100%}.min-w-full{min-width:100%}.max-w-sm{max-width:24rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.grow{flex-grow:1}.grow-0{flex-grow:0}.basis-\[30px\]{flex-basis:30px}.border-separate{border-collapse:initial}.border-spacing-0Line truncated
-38
View File
@@ -1,38 +0,0 @@
THISDIR = $(realpath $(CURDIR))
ROOTDIR = $(realpath $(CURDIR)/../../..)
DOCKER ?= docker run --rm $(DA) -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) espressif/idf
CMD ?= idf.py build
PORT ?= /dev/ttyUSB0
all: example
example:
true
build: Makefile $(wildcard main/*)
$(DOCKER) $(CMD)
flash:
flash: CMD = idf.py flash
flash: DA = --device $(PORT)
flash: build
.PHONY: build
dashboard.hex: build
esputil mkhex \
0x8000 build/partition_table/partition-table.bin \
0x1000 build/bootloader/bootloader.bin \
0x100000 build/mongoose-esp32-example.bin > $@
flash2: dashboard.hex
esputil -p $(PORT) -b 921600 -fp 0x220 flash dashboard.hex
esputil -p $(PORT) monitor
ESPTOOL ?= esptool.py
flash3:
cd build && $(ESPTOOL) --chip esp32 -p $(PORT) -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio --flash_freq 40m --flash_size 2MB 0x8000 partition_table/partition-table.bin 0x1000 bootloader/bootloader.bin 0x100000 mongoose-esp32-example.bin
clean:
test -d build && $(DOCKER) rm -rf build sdkconfig || true
-265
View File
@@ -1,265 +0,0 @@
// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved
#include "mongoose.h"
#include "net.h"
#define WIFI_SSID "YOUR_WIFI_NETWORK_NAME" // SET THIS!
#define WIFI_PASS "YOUR_WIFI_PASSWORD" // SET THIS!
void app_main(void) {
// Setup wifi. This function is implemented in wifi.c
// It blocks until connected to the configured WiFi network
void wifi_init(const char *ssid, const char *pass);
wifi_init(WIFI_SSID, WIFI_PASS);
// Connected to WiFi, now start HTTP server
struct mg_mgr mgr;
mg_log_set(MG_LL_DEBUG); // Set log level
mg_mgr_init(&mgr);
MG_INFO(("Mongoose version : v%s", MG_VERSION));
MG_INFO(("Listening on : %s", HTTP_URL));
#if MG_ENABLE_MBEDTLS
MG_INFO(("Listening on : %s", HTTPS_URL));
#endif
web_init(&mgr);
for (;;) mg_mgr_poll(&mgr, 1000); // Infinite event loop
}
#if MG_DEVICE == MG_DEVICE_CUSTOM
void *mg_flash_start(void) {
return NULL;
}
size_t mg_flash_size(void) {
return 0;
}
size_t mg_flash_sector_size(void) {
return 0;
}
size_t mg_flash_write_align(void) {
return 0;
}
int mg_flash_bank(void) {
return 0;
}
bool mg_flash_erase(void *location) {
(void) location;
return false;
}
bool mg_flash_swap_bank(void) {
return true;
}
bool mg_flash_write(void *addr, const void *buf, size_t len) {
(void) addr, (void) buf, (void) len;
return false;
}
void mg_device_reset(void) {
esp_restart();
}
#endif
#if MG_OTA == MG_OTA_CUSTOM
#include "esp_app_format.h"
#include "esp_ota_ops.h"
static size_t s_size = 0; // Firmware size to flash. In-progress indicator
static bool rx_checked = false; // Whether firmware being received has been checked as valid
const esp_partition_t * update_partition = NULL; // The partition the update is being applied to
esp_ota_handle_t update_handle = 0; // Handle of the current update process
const esp_partition_t * get_partition_from_fw(int fw) {
if (MG_FIRMWARE_CURRENT == fw) {
return esp_ota_get_running_partition();
}
const esp_partition_t * p = esp_ota_get_last_invalid_partition();
if (NULL == p) {
p = esp_ota_get_next_update_partition(NULL);
}
return p;
}
// Returns true if the data buffer contains the header of a valid firmware
const size_t fw_size_required = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) + sizeof(esp_app_desc_t);
bool check_fw_header(const void* buf, size_t len) {
// Ensure we have received enough data to do the check
if (len < fw_size_required) {
MG_ERROR(("Insufficient data to check firmware header - %d bytes, require %d bytes", len, fw_size_required));
return false;
}
// Check the magic word of the received firmare
esp_app_desc_t* rx_app_info = (esp_app_desc_t*)(((char*)buf) + sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t));
if (ESP_APP_DESC_MAGIC_WORD != rx_app_info->magic_word) {
MG_ERROR(("Invalid app - invalid magic word"));
return false;
}
MG_INFO(("Received firmware: %s %s", rx_app_info->project_name, rx_app_info->version));
// Get the name/version of the running firmware
const esp_partition_t *current = esp_ota_get_running_partition();
esp_app_desc_t curr_app_info;
esp_err_t res = esp_ota_get_partition_description(current, &curr_app_info);
if (ESP_OK != res) {
MG_ERROR(("Unable to get name/version of running firmware"));
return false;
}
MG_INFO(("Running firmware: %s %s", curr_app_info.project_name, curr_app_info.version));
// Check the name of the new firmware is the same as the old firmware
if (memcmp(curr_app_info.project_name, rx_app_info->project_name, sizeof(curr_app_info.project_name)) != 0) {
MG_ERROR(("Firmware name is different. Wrong firmware uploaded! Current %s Uploaded %s", curr_app_info.project_name, rx_app_info->project_name));
return false;
}
// Check the version of the new firmware is different from the old firmware
if (memcmp(curr_app_info.version, rx_app_info->version, sizeof(curr_app_info.version)) == 0) {
MG_ERROR(("Firmware version is the same. Wrong firmware uploaded! Current %s, Uploaded %s", curr_app_info.version, rx_app_info->version));
//return false;
}
return true;
}
bool mg_ota_begin(size_t new_firmware_size) {
rx_checked = false;
if (s_size) {
MG_ERROR(("OTA already in progress. Call mg_ota_end()"));
return false;
}
int partition_size = mg_ota_size(MG_FIRMWARE_PREVIOUS);
if (new_firmware_size > partition_size) {
MG_ERROR(("Firmware %lu bytes, max %lu", new_firmware_size, partition_size));
return false;
}
update_partition = esp_ota_get_next_update_partition(NULL);
if (NULL == update_partition) {
MG_ERROR(("esp_ota_get_next_update_partition returned NULL"));
return false;
}
esp_err_t res = esp_ota_begin(update_partition, OTA_WITH_SEQUENTIAL_WRITES, &update_handle);
if (res != ESP_OK) {
esp_ota_abort(update_handle);
MG_ERROR(("esp_ota_begin failed (%s)", esp_err_to_name(res)));
return false;
}
s_size = new_firmware_size;
MG_INFO(("Starting OTA, firmware size %lu", s_size));
return true;
}
bool mg_ota_write(const void *buf, size_t len) {
if (s_size == 0) {
MG_ERROR(("OTA is not started, call mg_ota_begin()"));
return false;
}
if (!rx_checked) {
if (!check_fw_header(buf, len)) {
return false;
}
rx_checked = true;
}
esp_err_t res = esp_ota_write(update_handle, buf, len);
if (res != ESP_OK) {
esp_ota_abort(update_handle);
MG_ERROR(("esp_ota_write FAILED (%s)", esp_err_to_name(res)));
return false;
}
return true;
}
bool mg_ota_end(void) {
if (0 == s_size) {
MG_INFO(("Finishing OTA: fail"));
return false;
}
s_size = 0;
esp_err_t err = esp_ota_end(update_handle);
if (err != ESP_OK) {
MG_ERROR(("esp_ota_end failed (%s)!", esp_err_to_name(err)));
return false;
}
err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) {
MG_ERROR(("esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)));
return false;
}
return true;
}
bool mg_ota_commit(void) {
esp_ota_mark_app_valid_cancel_rollback();
return true;
}
bool mg_ota_rollback(void) {
if(esp_ota_check_rollback_is_possible()) {
esp_ota_mark_app_invalid_rollback_and_reboot();
return true;
}
MG_ERROR(("Rollback NOT possible"));
return false;
}
int mg_ota_status(int fw) {
const esp_partition_t *p = get_partition_from_fw(fw);
if (NULL == p) {
return 0;
}
int status = MG_OTA_UNAVAILABLE;
esp_ota_img_states_t img_state = ESP_OTA_IMG_UNDEFINED;
esp_err_t res = esp_ota_get_state_partition(p, &img_state);
if (ESP_OK == res) {
if (ESP_OTA_IMG_VALID == img_state) {
status = MG_OTA_COMMITTED;
} else if (ESP_OTA_IMG_UNDEFINED == img_state) {
status = MG_OTA_UNCOMMITTED;
} else if (ESP_OTA_IMG_INVALID == img_state) {
status = MG_OTA_UNAVAILABLE;
} else if (ESP_OTA_IMG_ABORTED == img_state) {
status = MG_OTA_UNAVAILABLE;
} else if (ESP_OTA_IMG_NEW == img_state) {
status = MG_OTA_FIRST_BOOT;
} else if (ESP_OTA_IMG_PENDING_VERIFY == img_state) {
status = MG_OTA_UNCOMMITTED;
}
}
return status;
}
uint32_t mg_ota_crc32(int fw) {
(void) fw;
return 0;
}
uint32_t mg_ota_timestamp(int fw) {
const esp_partition_t *p = get_partition_from_fw(fw);
esp_app_desc_t app;
esp_err_t res = esp_ota_get_partition_description(p, &app);
if (ESP_OK != res)
{
return 0;
}
struct tm datetime = {};
if (NULL == strptime(app.date, "%b %d %Y", &datetime))
{
return 0;
}
if (NULL == strptime(app.time, "%H:%M:%S", &datetime))
{
return 0;
}
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
@@ -1,6 +0,0 @@
#define MG_ARCH MG_ARCH_ESP32
#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
-23
View File
@@ -1,23 +0,0 @@
# Mongoose as a MicroPython user module on the ESP32
The most basic usage is:
```python
import network
import mongoose
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
sta_if.connect("<SSID>", "<PASSWORD>")
while not sta_if.isconnected():
pass
mongoose.init()
while True:
mongoose.poll(1000)
```
Check [_thread](https://docs.micropython.org/en/latest/library/_thread.html) support for more advanced usage
https://docs.micropython.org/en/latest/develop/cmodules.html
@@ -1 +0,0 @@
../../../micropython/mongoose/micropython.cmake
@@ -1 +0,0 @@
../../../micropython/mongoose/micropython.mk
@@ -1 +0,0 @@
../../../micropython/mongoose/module.c
-32
View File
@@ -1,32 +0,0 @@
CWD = $(realpath $(CURDIR))
MNT = $(realpath $(CURDIR)/../../..)
PORT ?= /dev/ttyUSB0
CMD ?= build
all: example
example:
true
build: Makefile $(wildcard main/*)
docker run --rm $(DA) -v $(MNT):$(MNT) -w $(CWD) espressif/idf idf.py $(CMD)
flash:
flash: CMD = flash
flash: DA = --device $(PORT)
flash: build
.PHONY: build
bridge.hex: build
esputil mkhex \
0x8000 build/partition_table/partition-table.bin \
0x1000 build/bootloader/bootloader.bin \
0x100000 build/mongoose-esp32-example.bin > $@
flash2: bridge.hex
esputil -p $(PORT) -b 921600 -fp 0x220 flash bridge.hex
esputil -p $(PORT) monitor
clean:
rm -rf build
-1
View File
@@ -1 +0,0 @@
../../../uart-bridge/net.c
@@ -1 +0,0 @@
../../../uart-bridge/packed_fs.c
@@ -1,45 +0,0 @@
THISDIR = $(realpath $(CURDIR))
ROOTDIR = $(realpath $(CURDIR)/../../..)
DOCKER ?= docker run --rm $(DA) -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) docker.io/mdashnet/8266
CMD ?= make -C src defconfig app
PORT ?= /dev/ttyUSB0
all: example
example:
true
build: Makefile $(wildcard src/main/*)
$(DOCKER) $(CMD)
flash:
flash: CMD = python /esp/components/esptool_py/esptool/esptool.py \
--chip esp8266 --port $(PORT) --baud 115200 --before default_reset \
--after hard_reset write_flash -z --flash_mode dio --flash_freq 40m \
--flash_size 2MB 0x10000 $(THISDIR)/src/build/mongoose-example.bin
flash: DA = --device $(PORT)
flash: build
buildall:
buildall: CMD = make -C src all
buildall: build
flashall:
flashall: CMD = python /esp/components/esptool_py/esptool/esptool.py \
--chip esp8266 --port $(PORT) --baud 115200 --before default_reset \
--after hard_reset write_flash -z --flash_mode dio --flash_freq 40m \
--flash_size 2MB 0x0 $(THISDIR)/src/build/bootloader/bootloader.bin \
0x10000 $(THISDIR)/src/build/mongoose-example.bin \
0x8000 $(THISDIR)/src/build/partitions_singleapp.bin
flashall: DA = --device $(PORT)
flashall: build
monitor:
monitor: CMD = /esp/tools/idf_monitor.py --port $(PORT) $(THISDIR)/src/build/mongoose-example.elf
monitor: build
.PHONY: build
clean:
test -d src/build && $(DOCKER) rm -rf src/build || true
-1
View File
@@ -1 +0,0 @@
../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../mongoose.h
@@ -1,9 +0,0 @@
NAME ?= $(notdir $(CURDIR))
build:
git clone --depth 1 https://github.com/mongoose-examples/$(NAME)
cp ./../../../mongoose.[ch] $(NAME)
make -C $(NAME) build
clean:
rm -rf $(NAME)
@@ -1,41 +0,0 @@
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
all build example: firmware.bin
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
firmware.elf: cmsis_core cmsis_xmc7 $(SOURCES) hal.h link.ld Makefile
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(LDFLAGS) -o $@
arm-none-eabi-size $@
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
clean:
$(RM) firmware.* *.su cmsis_core cmsis_xmc7 *.zip
-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;
}
@@ -1,53 +0,0 @@
CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion
CFLAGS += -Wformat-truncation -fno-common -Wconversion
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include
CFLAGS += -D__SAME54P20A__ -Icmsis_sam/include
CFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp
LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
SOURCES = main.c syscalls.c startup.c
# Mongoose-specific source code files and build options. See https://mongoose.ws/documentation/#build-options
SOURCES += mongoose.c net.c packed_fs.c
CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_LINES=1
CFLAGS += -DMG_ENABLE_DRIVER_SAME54=1 -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_PACKED_FS=1 $(CFLAGS_EXTRA)
# 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
else
RM = rm -rf
endif
build: firmware.bin
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
firmware.elf: cmsis_core cmsis_sam hal.h link.ld Makefile $(SOURCES)
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@
flash: firmware.bin
bossac -p /dev/cu.usb* -w -v -b $<
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
mkdir $@ && cd $@ && unzip ../$@.zip
# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/9
update: firmware.bin
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
test update: CFLAGS += -DUART_DEBUG=USART1
test: update
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.* cmsis_core cmsis_sam *.zip
@@ -1,78 +0,0 @@
// SPDX-FileCopyrightText: 2022-2023 Cesanta Software Limited
// SPDX-License-Identifier: MIT
#include "hal.h"
#include "mongoose.h"
#include "net.h"
#define BLINK_PERIOD_MS 500 // LED blinking period in millis
#define LOG_PERIOD_MS 1000 // Info log period in millis
void SystemInit(void) { // Called automatically by startup code
clock_init();
rng_init();
}
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) {
struct mg_tcpip_if *ifp = arg; // show network stats
const char *names[] = {"down", "up", "req", "ready"};
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_input(BUTTON_PIN);
gpio_output(LED_PIN);
uart_init(UART_DEBUG, 115200);
ethernet_init();
MG_INFO(("Starting, CPU freq %g MHz", (double) clock_sys_freq() / 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_same54_data driver_data = {.mdc_cr = 5};
struct mg_tcpip_if mif = {.mac = GENERATE_LOCALLY_ADMINISTERED_MAC()/*{2, 3, 4, 5, 6, 7}*/,
// 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_same54,
.driver_data = &driver_data};
mg_tcpip_init(&mgr, &mif);
mg_timer_add(&mgr, LOG_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,54 +0,0 @@
CFLAGS = -W -Wall -Wextra -Wundef -Wshadow -Wdouble-promotion
CFLAGS += -Wformat-truncation -fno-common -Wconversion
CFLAGS += -g3 -Os -ffunction-sections -fdata-sections
CFLAGS += -I. -Icmsis_core/CMSIS/Core/Include
CFLAGS += -D__SAME54P20A__ -Icmsis_sam/include
CFLAGS += -mcpu=cortex-m4 -mthumb -mfloat-abi=softfp
LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
SOURCES = main.c syscalls.c startup.c
# Mongoose-specific source code files and build options. See https://mongoose.ws/documentation/#build-options
SOURCES += mongoose.c
CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_LINES=1
CFLAGS += -DMG_ENABLE_DRIVER_SAME54=1 -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_PACKED_FS=1 $(CFLAGS_EXTRA)
# 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
else
RM = rm -rf
endif
build: firmware.bin
firmware.bin: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
firmware.elf: cmsis_core cmsis_sam hal.h link.ld Makefile $(SOURCES)
arm-none-eabi-gcc $(SOURCES) $(CFLAGS) $(CFLAGS_EXTRA) $(LDFLAGS) -o $@
flash: firmware.bin
bossac -p /dev/cu.usb* -w -v -b $<
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
mkdir $@ && cd $@ && unzip ../$@.zip
# Automated test via https://vcon.io/automated-firmware-tests/. Set VCON_API_KEY and update DEVICE_URL
DEVICE_URL ?= https://dash.vcon.io/api/v3/devices/9
update: firmware.bin
curl --fail-with-body -su :$(VCON_API_KEY) $(DEVICE_URL)/ota --data-binary @$<
test update: CFLAGS += -DUART_DEBUG=USART1
test: update
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
grep 'RECEIVED hello' /tmp/output.txt # Check for MQTT success
clean:
$(RM) firmware.* cmsis_core cmsis_sam *.zip
@@ -1,119 +0,0 @@
// Copyright (c) 2023 Cesanta Software Limited
// All rights reserved
#include "hal.h"
#include "mongoose.h"
static const char *s_url = "mqtt://broker.hivemq.com:1883";
static const char *s_sub_topic = "mg/+/test"; // Publish topic
static const char *s_pub_topic = "mg/clnt/test"; // Subscribe topic
static const uint8_t s_qos = 1; // MQTT QoS
static struct mg_connection *s_conn; // Client connection
void SystemInit(void) { // Called automatically by startup code
clock_init();
rng_init();
}
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 fn(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_OPEN) {
MG_INFO(("%lu CREATED", c->id));
// c->is_hexdumping = 1;
} else if (ev == MG_EV_ERROR) {
// On error, log error message
MG_ERROR(("%lu ERROR %s", c->id, (char *) ev_data));
} else if (ev == MG_EV_MQTT_OPEN) {
// MQTT connect is successful
struct mg_str subt = mg_str(s_sub_topic);
struct mg_str pubt = mg_str(s_pub_topic), data = mg_str("hello");
MG_INFO(("%lu CONNECTED to %s", c->id, s_url));
struct mg_mqtt_opts sub_opts;
memset(&sub_opts, 0, sizeof(sub_opts));
sub_opts.topic = subt;
sub_opts.qos = s_qos;
mg_mqtt_sub(c, &sub_opts);
MG_INFO(("%lu SUBSCRIBED to %.*s", c->id, (int) subt.len, subt.buf));
struct mg_mqtt_opts pub_opts;
memset(&pub_opts, 0, sizeof(pub_opts));
pub_opts.topic = pubt;
pub_opts.message = data;
pub_opts.qos = s_qos, pub_opts.retain = false;
mg_mqtt_pub(c, &pub_opts);
MG_INFO(("%lu PUBLISHED %.*s -> %.*s", c->id, (int) data.len, data.buf,
(int) pubt.len, pubt.buf));
} else if (ev == MG_EV_MQTT_MSG) {
// When we get echo response, print it
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));
} else if (ev == MG_EV_CLOSE) {
MG_INFO(("%lu CLOSED", c->id));
s_conn = NULL; // Mark that we're closed
}
}
// Timer function - recreate client connection if it is closed
static void timer_fn(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg;
struct mg_mqtt_opts opts = {.clean = true,
.qos = s_qos,
.topic = mg_str(s_pub_topic),
.version = 4,
.message = mg_str("bye")};
if (s_conn == NULL) s_conn = mg_mqtt_connect(mgr, s_url, &opts, fn, NULL);
}
int main(void) {
gpio_input(BUTTON_PIN);
gpio_output(LED_PIN);
uart_init(UART_DEBUG, 115200);
ethernet_init();
MG_INFO(("Starting, CPU freq %g MHz", (double) clock_sys_freq() / 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_same54_data driver_data = {.mdc_cr = 5};
struct mg_tcpip_if mif = {
.mac = GENERATE_LOCALLY_ADMINISTERED_MAC() /*{2, 3, 4, 5, 6, 7}*/,
// 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_same54,
.driver_data = &driver_data};
mg_tcpip_init(&mgr, &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..."));
mg_timer_add(&mgr, 3000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, &mgr);
MG_INFO(("Starting event loop"));
for (;;) {
mg_mgr_poll(&mgr, 0);
}
return 0;
}
@@ -1 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
-9
View File
@@ -1,9 +0,0 @@
# Mongoose as a MicroPython user module
The most basic usage is in `main.py`.
You'll have to configure Mongoose for your desired platform, this example runs on the `unix` port and Mongoose detects it as a known architecture and hence configures itself to use sockets and time base. For other platforms, you'll have to do your homework (there's plenty of Mongoose examples for several platforms); also check respective MicroPython build instructions.
Check [_thread](https://docs.micropython.org/en/latest/library/_thread.html) support for more advanced usage
https://docs.micropython.org/en/latest/develop/cmodules.html
-55
View File
@@ -1,55 +0,0 @@
PROG ?= ./example # Program we are building
PACK ?= ./pack # Packing executable
DELETE = rm -rf # Command to remove files
GZIP ?= gzip # For compressing files in web_root/
OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c net.c packed_fs.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
# Mongoose build options. See https://mongoose.ws/documentation/#build-options
CFLAGS_MONGOOSE += -DMG_ENABLE_PACKED_FS=1
ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To use VC: make CC=cl CFLAGS=/MD OUT=/Feprog.exe
PROG = example.exe # Use .exe suffix for the binary
PACK = pack.exe # Packing executable
CC = gcc # Use MinGW gcc compiler
CFLAGS += -lws2_32 # Link against Winsock library
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
GZIP = echo # No gzip on Windows
endif
# Default target. Build and run program
all: $(PROG)
$(RUN) $(PROG) $(ARGS)
# Build program from sources
$(PROG): $(SOURCES)
$(CC) $(SOURCES) $(CFLAGS) $(CFLAGS_MONGOOSE) $(CFLAGS_EXTRA) $(OUT)
# Bundle JS libraries (preact, preact-router, ...) into a single file
web_root/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
web_root/main.css: web_root/index.html $(wildcard web_root/*.js)
npx tailwindcss -o $@ --minify
# Generate packed filesystem for serving Web UI
packed_fs.c: $(wildcard web_root/*) $(wildcard certs/*) Makefile web_root/main.css web_root/bundle.js
$(GZIP) web_root/*
$(CC) ../../test/pack.c -o $(PACK)
$(PACK) web_root/* certs/* > $@
$(GZIP) -d web_root/*
mbedtls:
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
$(PROG): mbedtls
endif
# Cleanup. Delete built program and all build artifacts
clean:
$(DELETE) $(PROG) $(PACK) *.o *.obj *.exe *.bin *.dSYM mbedtls
-1
View File
@@ -1 +0,0 @@
../device-dashboard/certs
-1
View File
@@ -1 +0,0 @@
../../mongoose.c
-1
View File
@@ -1 +0,0 @@
../../mongoose.h
-304
View File
@@ -1,304 +0,0 @@
// Copyright (c) 2023 Cesanta Software Limited
// All rights reserved
#include "net.h"
// Device settings
struct device_settings {
uint32_t magic;
int log_level;
bool mqtt_enabled;
char mqtt_server_url[64];
char mqtt_topic_tx[16];
char mqtt_topic_rx[16];
};
struct conndata {
uint64_t expiration_time; // Modbus request timeout
unsigned long id; // Connection ID waiting for the Modbus response
};
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;
s->log_level = MG_LL_DEBUG;
mg_snprintf(s->mqtt_server_url, sizeof(s->mqtt_server_url), "%s",
"mqtt://broker.hivemq.com:1883");
mg_snprintf(s->mqtt_topic_tx, sizeof(s->mqtt_topic_tx), "%s", "modbus1/tx");
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);
}
static void setfromjson(struct mg_str json, const char *jsonpath, char *buf,
size_t len) {
char *val = mg_json_get_str(json, jsonpath);
if (val != NULL) mg_snprintf(buf, len, "%s", val);
free(val);
}
static void handle_settings_set(struct mg_connection *c, struct mg_str body) {
struct device_settings settings;
memset(&settings, 0, sizeof(settings));
set_default_settings(&settings);
mg_json_get_bool(body, "$.mqtt_enabled", &settings.mqtt_enabled);
settings.log_level = mg_json_get_long(body, "$.log_level", MG_LL_INFO);
setfromjson(body, "$.mqtt_server_url", settings.mqtt_server_url,
sizeof(settings.mqtt_server_url));
setfromjson(body, "$.mqtt_topic_rx", settings.mqtt_topic_rx,
sizeof(settings.mqtt_topic_rx));
setfromjson(body, "$.mqtt_topic_tx", settings.mqtt_topic_tx,
sizeof(settings.mqtt_topic_tx));
s_settings = settings;
bool ok = web_save_settings(&s_settings, sizeof(s_settings));
mg_http_reply(c, 200, s_json_header,
"{%m:%s,%m:%m}", //
MG_ESC("status"), ok ? "true" : "false", //
MG_ESC("message"), MG_ESC(ok ? "Success" : "Failed"));
}
static void handle_settings_get(struct mg_connection *c) {
mg_http_reply(c, 200, s_json_header,
"{%m:%s,%m:%d,%m:%m,%m:%m,%m:%m}\n", //
MG_ESC("mqtt_enabled"),
s_settings.mqtt_enabled ? "true" : "false", //
MG_ESC("log_level"), s_settings.log_level, //
MG_ESC("mqtt_server_url"), MG_ESC(s_settings.mqtt_server_url),
MG_ESC("mqtt_topic_rx"), MG_ESC(s_settings.mqtt_topic_rx),
MG_ESC("mqtt_topic_tx"), MG_ESC(s_settings.mqtt_topic_tx));
}
// Modbus handler function
static void mfn(struct mg_connection *c, int ev, void *ev_data) {
struct conndata *cd = (struct conndata *) c->data;
if (ev == MG_EV_READ) {
MG_INFO(("%lu RECEIVED %lu", c->id, c->recv.len));
if (c->recv.len < 8) return; // Less than minimum length, buffer more
uint16_t len = mg_ntohs(*(uint16_t *) &c->recv.buf[4]); // PDU length
if (c->recv.len < len + 4U) return; // Partial frame, buffer more
// Notify parent connection
for (struct mg_connection *t = c->mgr->conns; t != NULL; t = t->next) {
if (t->id == cd->id) mg_call(t, MG_EV_USER, &c->recv);
}
c->is_closing = 1;
} else if (MG_EV_POLL) {
// MG_INFO(("%lu closing tmout %llu", c->id, cd->expiration_time));
if (cd->expiration_time > 0 && cd->expiration_time < mg_millis()) {
c->is_closing = 1;
}
}
(void) ev_data;
}
static void send8(struct mg_connection *c, uint8_t val) {
mg_send(c, &val, sizeof(val));
}
static void send16(struct mg_connection *c, uint16_t val) {
send8(c, (uint8_t) (val >> 8) & 255);
send8(c, (uint8_t) (val & 255));
}
static struct mg_connection *start_modbus_request(struct mg_mgr *mgr,
struct mg_str json,
unsigned long cid) {
struct mg_connection *c = NULL;
char *url = mg_json_get_str(json, "$.url");
long timeout = mg_json_get_long(json, "$.timeout", 750);
uint8_t id = (uint8_t) mg_json_get_long(json, "$.id", 1);
uint16_t reg = (uint16_t) mg_json_get_long(json, "$.reg", 1);
uint8_t func = (uint8_t) mg_json_get_long(json, "$.func", 0);
uint16_t nregs = (uint16_t) mg_json_get_long(json, "$.nregs", 1);
MG_INFO(("%lu REQUEST: %.*s", cid, json.len, json.buf));
if (func == 0) {
MG_ERROR(("Set func to a valid modbus function code"));
} else if ((c = mg_connect(mgr, url, mfn, NULL)) == NULL) {
MG_ERROR(("Failed to start modbus connection at %M", MG_ESC(url)));
} else {
send16(c, 1); // TID. Use random?
send16(c, 0); // Protocol identifier: 0 (modbus)
uint16_t *lp = (uint16_t *) &c->send.buf[c->send.len];
send16(c, 0); // Length: to be set later
size_t len = c->send.len;
send8(c, id); // Client ID
send8(c, func); // Function
if (func == 3 || func == 4 || func == 6 || func == 16) {
send16(c, reg); // Start register
send16(c, nregs); // Number of registers
if (func == 16) { // Fill in register values to write
send8(c, (uint8_t) (nregs * 2)); // Send number of bytes
for (uint16_t i = 0; i < nregs; i++) {
char path[20];
mg_snprintf(path, sizeof(path), "$.values[%hu]", i);
uint16_t r = (uint16_t) mg_json_get_long(json, path, 0);
send16(c, r);
}
}
} else if (func == 43) {
send8(c, 14); // MEI
send8(c, 1); // Basic device ID: 1
send8(c, 0); // Object ID: 0 (vendor name)
}
*lp = mg_htons((uint16_t) (c->send.len - len)); // Set length field
mg_hexdump(c->send.buf, c->send.len);
MG_INFO(("%lu SENDING %lu", c->id, c->send.len));
struct conndata *cd = (struct conndata *) c->data;
cd->id = cid; // Store parent connection ID
cd->expiration_time = mg_millis() + timeout;
}
free(url);
return c;
}
static void handle_modbus_exec(struct mg_connection *c, struct mg_str body) {
struct mg_connection *mc = start_modbus_request(c->mgr, body, c->id);
if (mc == NULL) {
mg_http_reply(c, 200, s_json_header, "false\n");
} else {
struct conndata *cd = (struct conndata *) c->data;
cd->expiration_time = mg_millis() + 1500;
}
}
// Print modbus response
static size_t print_mb_resp(void (*out)(char, void *), void *ptr, va_list *ap) {
int func = va_arg(*ap, int);
size_t len = va_arg(*ap, size_t);
uint8_t *buf = va_arg(*ap, uint8_t *);
size_t n = 0;
if (func == 3 || func == 4) {
// For "multiple" read responses, print registers
n += mg_xprintf(out, ptr, "[");
for (size_t ofs = 1; ofs < len; ofs += 2) {
uint16_t reg = mg_ntohs(*(uint8_t *) &buf[ofs]);
n += mg_xprintf(out, ptr, "%s%hu", ofs == 1 ? "" : ",", reg);
}
n += mg_xprintf(out, ptr, "]");
} else if (func == 43) {
n += mg_xprintf(out, ptr, "{");
if (len >= 6) {
n += mg_xprintf(out, ptr, "%m:%d", MG_ESC("mei"), buf[0]);
n += mg_xprintf(out, ptr, ",%m:%d", MG_ESC("devid"), buf[1]);
n += mg_xprintf(out, ptr, ",%m:%d", MG_ESC("conformity"), buf[2]);
n += mg_xprintf(out, ptr, ",%m:%d", MG_ESC("more"), buf[3]);
n += mg_xprintf(out, ptr, ",%m:%d", MG_ESC("next"), buf[4]);
n += mg_xprintf(out, ptr, ",%m:[", MG_ESC("objects"));
size_t ofs = 6;
while (ofs < len) {
if (ofs > 6) n += mg_xprintf(out, ptr, ",");
n += mg_xprintf(out, ptr, "{");
n += mg_xprintf(out, ptr, "%m:%d", MG_ESC("id"), buf[ofs++]);
if (ofs < len) {
uint8_t olen = buf[ofs++];
if (olen > (uint8_t) (len - ofs)) olen = (uint8_t) (len - ofs);
n += mg_xprintf(out, ptr, ",%m:%m", MG_ESC("value"), mg_print_esc,
olen, &buf[ofs]);
ofs += olen;
}
n += mg_xprintf(out, ptr, "}");
}
n += mg_xprintf(out, ptr, "]");
}
n += mg_xprintf(out, ptr, "}");
} else {
n += mg_xprintf(out, ptr, "null");
}
return n;
}
// HTTP request handler function
static void fn(struct mg_connection *c, int ev, void *ev_data) {
struct conndata *cd = (struct conndata *) c->data;
if (ev == MG_EV_ACCEPT) {
if (c->fn_data != NULL) { // TLS listener!
struct mg_tls_opts opts = {0};
opts.cert = mg_unpacked("/certs/server_cert.pem");
opts.key = mg_unpacked("/certs/server_key.pem");
mg_tls_init(c, &opts);
}
} else 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/settings/get"), NULL)) {
handle_settings_get(c);
} else if (mg_match(hm->uri, mg_str("/api/settings/set"), NULL)) {
handle_settings_set(c, hm->body);
} else if (mg_match(hm->uri, mg_str("/api/settings/set"), NULL)) {
handle_settings_set(c, hm->body);
} 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;
memset(&opts, 0, sizeof(opts));
#if MG_ARCH == MG_ARCH_UNIX || MG_ARCH == MG_ARCH_WIN32
opts.root_dir = "web_root"; // On workstations, use filesystem
#else
opts.root_dir = "/web_root"; // On embedded, use packed files
opts.fs = &mg_fs_packed;
#endif
mg_http_serve_dir(c, ev_data, &opts);
}
MG_DEBUG(("%lu %.*s %.*s", c->id, (int) hm->method.len, hm->method.buf,
(int) hm->uri.len, hm->uri.buf));
} else if (ev == MG_EV_POLL) {
if (cd->expiration_time > 0 && cd->expiration_time < mg_millis()) {
cd->expiration_time = 0;
mg_http_reply(c, 200, s_json_header, "false\n");
}
} else if (ev == MG_EV_USER) {
cd->expiration_time = 0; // Cleanup timeout setting
struct mg_iobuf *io = ev_data;
uint8_t f = io->buf[7];
mg_http_reply(c, 200, s_json_header, "{%m:%s,%m:%m,%m:%M}\n", //
MG_ESC("success"), "true", //
MG_ESC("raw"), mg_print_hex, io->len - 7, io->buf + 7, //
MG_ESC("data"), print_mb_resp, f, io->len - 8, io->buf + 8);
}
}
void web_init(struct mg_mgr *mgr) {
set_default_settings(&s_settings);
web_load_settings(&s_settings, sizeof(s_settings));
mg_http_listen(mgr, HTTP_URL, fn, NULL);
mg_http_listen(mgr, HTTPS_URL, fn, (void *) 1);
mg_timer_add(mgr, 10 * 60 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT,
timer_sntp_fn, mgr);
}
@@ -1,16 +0,0 @@
PWD := $(shell pwd)
NPX ?= npx
all: bundle.js main.css
make -C ../../../tutorials/http/http-server ARGS="-d $(PWD)"
# Bundle JS libraries (preact, preact-router, ...) into a single file
bundle.js:
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
main.css: index.html $(wildcard *.js)
$(NPX) tailwindcss -o $@ --minify
clean:
true
-334
View File
@@ -1,334 +0,0 @@
// Copyright (c) 2023 Cesanta Software Limited
// All rights reserved
#include "net.h"
char *g_mqtt_server_url = MQTT_SERVER_URL;
char *g_root_topic = MQTT_ROOT_TOPIC;
char *g_device_id;
static uint8_t s_qos = 1; // MQTT QoS
static struct mg_connection *s_conn; // MQTT Client connection
static struct mg_rpc *s_rpc = NULL; // List of registered RPC methods
#define MAX_PINS 20
struct device_config {
int log_level; // Device logging level, 0-4
int pin_count; // Number of pins to handle
uint16_t pin_map[MAX_PINS]; // Pins to handle
bool pin_state[MAX_PINS]; // State of the GPIO pins
};
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.
static void set_device_id(void) {
char buf[15] = "";
#ifdef _WIN32
unsigned long serial = 0;
if (GetVolumeInformationA("c:\\", NULL, 0, &serial, NULL, NULL, NULL, 0)) {
mg_snprintf(buf, sizeof(buf), "%lx", serial);
}
#elif defined(__APPLE__)
FILE *fp = popen(
"ioreg -l | grep IOPlatformSerialNumber | cut -d'\"' -f4 | tr -d $'\n'",
"r");
if (fp != NULL) {
fread(buf, 1, sizeof(buf), fp);
fclose(fp);
}
#elif defined(__linux__)
struct mg_str id = mg_file_read(&mg_fs_posix, "/etc/machine-id");
if (id.buf != NULL) {
mg_snprintf(buf, sizeof(buf), "%s", id.buf);
free((void *) id.buf);
}
#endif
if (buf[0] == '\0') mg_snprintf(buf, sizeof(buf), "%s", "MyDeviceID");
buf[sizeof(buf) - 1] = '\0';
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);
for (i = 0; i < num_elems; i++) {
len += mg_xprintf(out, ptr, "%s%hu", i ? "," : "", array[i]);
}
return len;
}
static size_t print_bools(void (*out)(char, void *), void *ptr, va_list *ap) {
bool *array = va_arg(*ap, bool *);
int i, len = 0, num_elems = va_arg(*ap, int);
for (i = 0; i < num_elems; i++) {
len += mg_xprintf(out, ptr, "%s%d", i ? "," : "", array[i]);
}
return len;
}
static void publish_status(struct mg_connection *c) {
char topic[100];
struct mg_mqtt_opts pub_opts;
struct mg_iobuf io = {0, 0, 0, 512};
// 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}}", //
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, //
MG_ESC(("pin_count")), s_device_config.pin_count, //
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);
memset(&pub_opts, 0, sizeof(pub_opts));
mg_snprintf(topic, sizeof(topic), "%s/%s/status", g_root_topic, g_device_id);
pub_opts.topic = mg_str(topic);
pub_opts.message = mg_str_n((char *) io.buf, io.len);
pub_opts.qos = s_qos;
pub_opts.retain = true;
mg_mqtt_pub(c, &pub_opts);
mg_iobuf_free(&io);
}
static void publish_response(struct mg_connection *c, char *buf, size_t len) {
struct mg_mqtt_opts pub_opts;
char topic[100];
mg_snprintf(topic, sizeof(topic), "%s/%s/tx", g_root_topic, g_device_id);
memset(&pub_opts, 0, sizeof(pub_opts));
pub_opts.topic = mg_str(topic);
pub_opts.message = mg_str_n(buf, len);
pub_opts.qos = s_qos;
mg_mqtt_pub(c, &pub_opts);
}
static void subscribe(struct mg_connection *c) {
char *rx_topic = mg_mprintf("%s/%s/rx", g_root_topic, g_device_id);
struct mg_str subt = mg_str(rx_topic);
struct mg_mqtt_opts sub_opts;
memset(&sub_opts, 0, sizeof(sub_opts));
sub_opts.topic = subt;
sub_opts.qos = s_qos;
mg_mqtt_sub(c, &sub_opts);
MG_INFO(("%lu SUBSCRIBED to %.*s", c->id, (int) subt.len, subt.buf));
free(rx_topic);
}
static void rpc_config_set(struct mg_rpc_req *r) {
struct device_config dc = s_device_config;
dc.pin_count = (int) mg_json_get_long(r->frame, "$.params.pin_count", -1);
dc.log_level = (int) mg_json_get_long(r->frame, "$.params.log_level", -1);
if (dc.log_level < 0 || dc.log_level > MG_LL_VERBOSE) {
mg_rpc_err(r, -32602, "Log level must be from 0 to 4");
} else if (dc.pin_count <= 0 || dc.pin_count > MAX_PINS) {
mg_rpc_err(r, -32602, "Pin count must be from 1 to %d", MAX_PINS);
} else {
int i, val;
for (i = 0; i < dc.pin_count; i++) {
char path[50];
mg_snprintf(path, sizeof(path), "$.params.pin_map[%d]", i);
dc.pin_map[i] = (uint16_t) mg_json_get_long(r->frame, path, 0);
mg_snprintf(path, sizeof(path), "$.params.pin_state[%d]", i);
if ((val = (int) mg_json_get_long(r->frame, path, -1)) >= 0) {
gpio_write(dc.pin_map[i], val);
}
dc.pin_state[i] = gpio_read(dc.pin_map[i]);
// MG_INFO(("%d %d %d", i, dc.pin_map[i], dc.pin_state[i]));
}
mg_log_set(dc.log_level);
s_device_config = dc;
mg_rpc_ok(r, "true");
}
}
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);
int len = 0;
char *buf = mg_json_get_b64(r->frame, "$.params.chunk", &len);
if (buf == NULL) {
mg_rpc_err(r, 1, "Error processing the binary chunk.");
} else {
if (ofs < 0 || tot < 0) {
mg_rpc_err(r, 1, "offset and total not set");
} else if (ofs == 0 && mg_ota_begin((size_t) tot) == false) {
mg_rpc_err(r, 1, "mg_ota_begin(%ld) failed\n", tot);
} else if (len > 0 && mg_ota_write(buf, len) == false) {
mg_rpc_err(r, 1, "mg_ota_write(%lu) @%ld failed\n", len, ofs);
mg_ota_end();
} else if (len == 0 && mg_ota_end() == false) {
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);
}
}
static void fn(struct mg_connection *c, int ev, void *ev_data) {
if (ev == MG_EV_OPEN) {
MG_INFO(("%lu CREATED", c->id));
// c->is_hexdumping = 1;
} else if (ev == MG_EV_CONNECT) {
MG_INFO(("Device %s is connected", g_device_id));
} else if (ev == MG_EV_ERROR) {
// On error, log error message
MG_ERROR(("%lu ERROR %s", c->id, (char *) ev_data));
} else if (ev == MG_EV_MQTT_OPEN) {
// MQTT connect is successful
MG_INFO(("%lu CONNECTED to %s", c->id, g_mqtt_server_url));
subscribe(c);
publish_status(c);
} else if (ev == MG_EV_MQTT_MSG) {
// When we get echo response, print it
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
struct mg_iobuf io = {0, 0, 0, 512};
struct mg_rpc_req r = {&s_rpc, NULL, mg_pfn_iobuf,
&io, NULL, {mm->data.buf, mm->data.len}};
size_t clipped_len = mm->data.len > 512 ? 512 : mm->data.len;
MG_INFO(("%lu RECEIVED %.*s <- %.*s", c->id, clipped_len, mm->data.buf,
mm->topic.len, mm->topic.buf));
mg_rpc_process(&r);
if (io.buf) {
publish_response(c, (char *) io.buf, io.len);
publish_status(c);
}
mg_iobuf_free(&io);
} else if (ev == MG_EV_CLOSE) {
MG_INFO(("%lu CLOSED", c->id));
s_conn = NULL; // Mark that we're closed
}
}
// Timer function - recreate client connection if it is closed
static void timer_reconnect(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg;
if (s_conn == NULL) {
struct mg_mqtt_opts opts;
char topic[100], message[100];
mg_snprintf(topic, sizeof(topic), "%s/%s/status", g_root_topic,
g_device_id);
mg_snprintf(message, sizeof(message), "{%m:%m,%m:{%m:%m}}",
MG_ESC("method"), MG_ESC("status.notify"), MG_ESC("params"),
MG_ESC("status"), MG_ESC("offline"));
memset(&opts, 0, sizeof(opts));
opts.clean = true;
opts.qos = s_qos;
opts.topic = mg_str(topic);
opts.version = 4;
opts.keepalive = MQTT_KEEPALIVE_SEC;
opts.retain = true;
opts.message = mg_str(message);
s_conn = mg_mqtt_connect(mgr, g_mqtt_server_url, &opts, fn, NULL);
}
}
static void timer_ping(void *arg) {
mg_mqtt_send_header(s_conn, MQTT_CMD_PINGREQ, 0, 0);
(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);
}
}
void web_init(struct mg_mgr *mgr) {
int i, ping_interval_ms = MQTT_KEEPALIVE_SEC * 1000 - 500;
set_device_id();
s_device_config.log_level = (int) mg_log_level;
s_device_config.pin_count = 5;
s_device_config.pin_map[0] = 10;
s_device_config.pin_map[1] = 11;
s_device_config.pin_map[2] = 12;
s_device_config.pin_map[3] = 13;
s_device_config.pin_map[4] = 25;
for (i = 0; i < s_device_config.pin_count; i++) {
s_device_config.pin_state[i] = gpio_read(s_device_config.pin_map[i]);
}
// 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);
mg_timer_add(mgr, 2000, MG_TIMER_REPEAT, timer_sntp, mgr);
}
void web_free(void) {
mg_rpc_del(&s_rpc, NULL); // Deallocate RPC handlers
free(g_device_id);
}
@@ -1,85 +0,0 @@
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
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: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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
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
@@ -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,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 +0,0 @@
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
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: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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
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
@@ -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,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 +0,0 @@
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
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: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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
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
@@ -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,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 +0,0 @@
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
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: firmware.elf
arm-none-eabi-objcopy -O binary $< $@
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
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
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
@@ -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,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,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,100 +0,0 @@
/*
* Copyright 2016-2023 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file rt1060-evk-xpresso-baremetal-builtin.c
* @brief Application entry point.
*/
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MIMXRT1062.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */
#include "hal.h"
#include "mongoose.h"
#include "net.h"
/* TODO: insert other definitions and declarations here. */
#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
TRNG_GetRandomData(TRNG, buf, len); // Init by BOARD_InitBootPeripherals()
}
static void timer_fn(void *arg) {
USER_LED_TOGGLE();
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));
}
/*
* @brief Application entry point.
*/
int main(void) {
/* Init board hardware. */
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif
SysTick_Config(SystemCoreClock / 1000); // Sys tick every 1ms
ethernet_init(); // Initialise ethernet pins and clocks
USER_LED_INIT(1);
test_init(); // for internal testing purposes only
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};
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 +0,0 @@
../../../../mongoose.c
@@ -1 +0,0 @@
../../../../mongoose.h
@@ -1 +0,0 @@
../../../device-dashboard/net.c
@@ -1 +0,0 @@
../../../device-dashboard/net.h
@@ -1 +0,0 @@
../../../device-dashboard/packed_fs.c
Loaded 100 of 4005 files, more files were not shown because too many files have changed in this diff. Show more