firmware streaming
This commit is contained in:
		
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "board": {
 | 
			
		||||
    "active_layer": 1,
 | 
			
		||||
    "active_layer": 31,
 | 
			
		||||
    "active_layer_preset": "",
 | 
			
		||||
    "auto_track_width": false,
 | 
			
		||||
    "hidden_netclasses": [],
 | 
			
		||||
 
 | 
			
		||||
@@ -59,27 +59,6 @@
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      "drc_exclusions": [
 | 
			
		||||
        "clearance|176260000|58370000|aaf09ae3-4ace-49d7-a050-44cb4c93d63b|ee82357c-9139-4ef8-a542-8725e3254fe0",
 | 
			
		||||
        "clearance|176660000|56270000|3da9717d-9800-42f9-97d1-56d23bf085aa|d5ef1ade-5176-4779-aaf0-75a583095401",
 | 
			
		||||
        "clearance|176660000|57520000|09cad967-1882-4dd3-8900-445282e228e5|aaecf811-fc68-432e-8032-ac52f2f4c632",
 | 
			
		||||
        "clearance|176660000|58770000|a8ab716a-cd1e-4842-ad8e-3d6d1db9770b|ee82357c-9139-4ef8-a542-8725e3254fe0",
 | 
			
		||||
        "clearance|177110000|56270000|3da9717d-9800-42f9-97d1-56d23bf085aa|02c6a0d6-d749-439d-8aea-2a55ff23d509",
 | 
			
		||||
        "clearance|177110000|57520000|09cad967-1882-4dd3-8900-445282e228e5|b83e5527-c0f3-4e61-bd5b-3079ced0723c",
 | 
			
		||||
        "clearance|177110000|58770000|a8ab716a-cd1e-4842-ad8e-3d6d1db9770b|173bfee3-0343-4ee2-91d9-e73a12cffe08",
 | 
			
		||||
        "clearance|177510000|56670000|444aab2b-3a9b-444e-b60c-b5b5ff830942|02c6a0d6-d749-439d-8aea-2a55ff23d509",
 | 
			
		||||
        "clearance|177510000|57120000|444aab2b-3a9b-444e-b60c-b5b5ff830942|b83e5527-c0f3-4e61-bd5b-3079ced0723c",
 | 
			
		||||
        "clearance|177510000|57920000|f1fd5816-e8bd-4ba6-9d53-54b58d25e2dc|b83e5527-c0f3-4e61-bd5b-3079ced0723c",
 | 
			
		||||
        "clearance|177510000|58370000|f1fd5816-e8bd-4ba6-9d53-54b58d25e2dc|173bfee3-0343-4ee2-91d9-e73a12cffe08",
 | 
			
		||||
        "clearance|177910000|56270000|9ce2df19-edf4-40d2-8e85-8c33008b8df0|02c6a0d6-d749-439d-8aea-2a55ff23d509",
 | 
			
		||||
        "clearance|177910000|57520000|c36efd78-869f-40e7-86fc-97e5ed683fec|b83e5527-c0f3-4e61-bd5b-3079ced0723c",
 | 
			
		||||
        "clearance|177910000|58770000|d668fda0-e4be-4e1f-95b8-8cd59a67cb21|173bfee3-0343-4ee2-91d9-e73a12cffe08",
 | 
			
		||||
        "clearance|178360000|56270000|9ce2df19-edf4-40d2-8e85-8c33008b8df0|50a027a2-4230-4974-b6cb-9aa24d6b855f",
 | 
			
		||||
        "clearance|178360000|57520000|c36efd78-869f-40e7-86fc-97e5ed683fec|ae02705d-fc4c-4270-b7c5-41495037850e",
 | 
			
		||||
        "clearance|178360000|58770000|d668fda0-e4be-4e1f-95b8-8cd59a67cb21|08dd9140-8967-4746-a078-91e200a8f376",
 | 
			
		||||
        "clearance|178760000|56670000|20ab85c0-b3f3-4826-a86d-065fee01e11f|50a027a2-4230-4974-b6cb-9aa24d6b855f",
 | 
			
		||||
        "clearance|178760000|57120000|20ab85c0-b3f3-4826-a86d-065fee01e11f|ae02705d-fc4c-4270-b7c5-41495037850e",
 | 
			
		||||
        "clearance|178760000|57920000|6b067fd3-d374-4937-8779-958994d9163b|ae02705d-fc4c-4270-b7c5-41495037850e",
 | 
			
		||||
        "clearance|178760000|58370000|6b067fd3-d374-4937-8779-958994d9163b|08dd9140-8967-4746-a078-91e200a8f376",
 | 
			
		||||
        "solder_mask_bridge|176260000|56670000|9839c562-7672-4ea8-a74d-bea83ae26677|d5ef1ade-5176-4779-aaf0-75a583095401",
 | 
			
		||||
        "solder_mask_bridge|176260000|57120000|9839c562-7672-4ea8-a74d-bea83ae26677|aaecf811-fc68-432e-8032-ac52f2f4c632",
 | 
			
		||||
        "solder_mask_bridge|176260000|57920000|aaf09ae3-4ace-49d7-a050-44cb4c93d63b|aaecf811-fc68-432e-8032-ac52f2f4c632",
 | 
			
		||||
 
 | 
			
		||||
@@ -7547,12 +7547,6 @@
 | 
			
		||||
		(color 0 0 0 0)
 | 
			
		||||
		(uuid "1b762162-080c-4e36-b68b-d3bd15571f83")
 | 
			
		||||
	)
 | 
			
		||||
	(junction
 | 
			
		||||
		(at 341.63 505.46)
 | 
			
		||||
		(diameter 0)
 | 
			
		||||
		(color 0 0 0 0)
 | 
			
		||||
		(uuid "1bbbffd7-dbd6-41b6-9df4-727135053c0b")
 | 
			
		||||
	)
 | 
			
		||||
	(junction
 | 
			
		||||
		(at 368.3 265.43)
 | 
			
		||||
		(diameter 0)
 | 
			
		||||
@@ -15217,7 +15211,7 @@
 | 
			
		||||
	)
 | 
			
		||||
	(wire
 | 
			
		||||
		(pts
 | 
			
		||||
			(xy 341.63 505.46) (xy 344.17 505.46)
 | 
			
		||||
			(xy 340.36 505.46) (xy 344.17 505.46)
 | 
			
		||||
		)
 | 
			
		||||
		(stroke
 | 
			
		||||
			(width 0)
 | 
			
		||||
@@ -15545,16 +15539,6 @@
 | 
			
		||||
		)
 | 
			
		||||
		(uuid "e67756b1-754a-4ec4-876d-f54bed44bc2a")
 | 
			
		||||
	)
 | 
			
		||||
	(wire
 | 
			
		||||
		(pts
 | 
			
		||||
			(xy 340.36 505.46) (xy 341.63 505.46)
 | 
			
		||||
		)
 | 
			
		||||
		(stroke
 | 
			
		||||
			(width 0)
 | 
			
		||||
			(type default)
 | 
			
		||||
		)
 | 
			
		||||
		(uuid "e6d8d8af-5a8f-4976-b5db-07b4b20cfb12")
 | 
			
		||||
	)
 | 
			
		||||
	(wire
 | 
			
		||||
		(pts
 | 
			
		||||
			(xy 445.77 410.21) (xy 443.23 410.21)
 | 
			
		||||
@@ -17498,28 +17482,6 @@
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
	)
 | 
			
		||||
	(global_label "GND"
 | 
			
		||||
		(shape input)
 | 
			
		||||
		(at 341.63 513.08 270)
 | 
			
		||||
		(fields_autoplaced yes)
 | 
			
		||||
		(effects
 | 
			
		||||
			(font
 | 
			
		||||
				(size 1.27 1.27)
 | 
			
		||||
			)
 | 
			
		||||
			(justify right)
 | 
			
		||||
		)
 | 
			
		||||
		(uuid "123ad6cd-9001-4ca2-8aad-4c81f4482755")
 | 
			
		||||
		(property "Intersheetrefs" "${INTERSHEET_REFS}"
 | 
			
		||||
			(at 341.63 519.2815 90)
 | 
			
		||||
			(effects
 | 
			
		||||
				(font
 | 
			
		||||
					(size 1.27 1.27)
 | 
			
		||||
				)
 | 
			
		||||
				(justify right)
 | 
			
		||||
				(hide yes)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
	)
 | 
			
		||||
	(global_label "GND"
 | 
			
		||||
		(shape input)
 | 
			
		||||
		(at 355.6 294.64 0)
 | 
			
		||||
@@ -31497,84 +31459,6 @@
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
	)
 | 
			
		||||
	(symbol
 | 
			
		||||
		(lib_id "Device:R")
 | 
			
		||||
		(at 341.63 509.27 0)
 | 
			
		||||
		(unit 1)
 | 
			
		||||
		(exclude_from_sim no)
 | 
			
		||||
		(in_bom yes)
 | 
			
		||||
		(on_board yes)
 | 
			
		||||
		(dnp no)
 | 
			
		||||
		(uuid "137170f3-e8d8-42e1-b7f6-c66c91ee3500")
 | 
			
		||||
		(property "Reference" "R71"
 | 
			
		||||
			(at 336.042 508.254 0)
 | 
			
		||||
			(effects
 | 
			
		||||
				(font
 | 
			
		||||
					(size 1.27 1.27)
 | 
			
		||||
				)
 | 
			
		||||
				(justify left)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
		(property "Value" "50k"
 | 
			
		||||
			(at 335.915 510.54 0)
 | 
			
		||||
			(effects
 | 
			
		||||
				(font
 | 
			
		||||
					(size 1.27 1.27)
 | 
			
		||||
				)
 | 
			
		||||
				(justify left)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
		(property "Footprint" "Resistor_SMD:R_0603_1608Metric"
 | 
			
		||||
			(at 339.852 509.27 90)
 | 
			
		||||
			(effects
 | 
			
		||||
				(font
 | 
			
		||||
					(size 1.27 1.27)
 | 
			
		||||
				)
 | 
			
		||||
				(hide yes)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
		(property "Datasheet" "~"
 | 
			
		||||
			(at 341.63 509.27 0)
 | 
			
		||||
			(effects
 | 
			
		||||
				(font
 | 
			
		||||
					(size 1.27 1.27)
 | 
			
		||||
				)
 | 
			
		||||
				(hide yes)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
		(property "Description" ""
 | 
			
		||||
			(at 341.63 509.27 0)
 | 
			
		||||
			(effects
 | 
			
		||||
				(font
 | 
			
		||||
					(size 1.27 1.27)
 | 
			
		||||
				)
 | 
			
		||||
				(hide yes)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
		(property "LCSC_PART_NUMBER" "C861451"
 | 
			
		||||
			(at 341.63 509.27 0)
 | 
			
		||||
			(effects
 | 
			
		||||
				(font
 | 
			
		||||
					(size 1.27 1.27)
 | 
			
		||||
				)
 | 
			
		||||
				(hide yes)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
		(pin "1"
 | 
			
		||||
			(uuid "56246497-6cc7-4d6c-9992-34288e860a05")
 | 
			
		||||
		)
 | 
			
		||||
		(pin "2"
 | 
			
		||||
			(uuid "b1f7f7f7-f002-48d7-a35e-f1e0135c646c")
 | 
			
		||||
		)
 | 
			
		||||
		(instances
 | 
			
		||||
			(project "PlantCtrlESP32"
 | 
			
		||||
				(path "/c26e8d55-0b6e-4c4e-b7c8-b1fed973201c"
 | 
			
		||||
					(reference "R71")
 | 
			
		||||
					(unit 1)
 | 
			
		||||
				)
 | 
			
		||||
			)
 | 
			
		||||
		)
 | 
			
		||||
	)
 | 
			
		||||
	(symbol
 | 
			
		||||
		(lib_id "Device:R")
 | 
			
		||||
		(at 279.908 388.112 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,13 @@ target = "riscv32imac-esp-espidf"
 | 
			
		||||
[target.riscv32imac-esp-espidf]
 | 
			
		||||
linker = "ldproxy"
 | 
			
		||||
runner = "espflash flash --monitor --partition-table partitions.csv -b no-reset" # Select this runner for espflash v2.x.x
 | 
			
		||||
#runner = "cargo runner"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# runner = "espflash flash --monitor --baud 921600 --partition-table partitions.csv -b no-reset" # Select this runner for espflash v2.x.x
 | 
			
		||||
# runner = espflash erase-parts otadata
 | 
			
		||||
 | 
			
		||||
#runner = "cargo runner"
 | 
			
		||||
rustflags = [ "--cfg",  "espidf_time64"] # Extending time_t for ESP IDF 5: https://github.com/esp-rs/rust/issues/110
 | 
			
		||||
 | 
			
		||||
[unstable]
 | 
			
		||||
 
 | 
			
		||||
@@ -2,9 +2,9 @@
 | 
			
		||||
;Verify Existing Firmware Version
 | 
			
		||||
;--------------------------------------------------------
 | 
			
		||||
W: AA 00 01 00
 | 
			
		||||
C: AA 00 00 01
 | 
			
		||||
C: AA 00 01 00
 | 
			
		||||
W: AA 00 02 00
 | 
			
		||||
C: AA 00 02 02
 | 
			
		||||
C: AA 00 02 00
 | 
			
		||||
;--------------------------------------------------------
 | 
			
		||||
;Unseal device
 | 
			
		||||
;--------------------------------------------------------
 | 
			
		||||
@@ -42,88 +42,88 @@ W: 16 00 0C 00 00 00 83 DE
 | 
			
		||||
W: 16 64 6D 01
 | 
			
		||||
X: 400
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 00 00 00 7E 22 B7 35 92 38 D0 0B F9 F1 E5 BC 00 00 14 B0 51 F6 C9 F4 14 52 09 21 32 6D 00 00 00 00 D0 7E
 | 
			
		||||
W: 16 64 0B 0D
 | 
			
		||||
W: 16 00 0A 00 00 00 7F 71 20 5C 94 08 98 C0 FB 50 00 00 00 00 13 88 51 F6 C9 F4 14 52 09 21 32 6D 00 00 00 00 D0 7E
 | 
			
		||||
W: 16 64 D1 0A
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 01 00 00 17 DF 00 00 17 F3 00 00 3A 36 FD 91 00 25 30 01 00 EF 02 11 05 01 00 00 10 01 00 3C 00 50 3C 00
 | 
			
		||||
W: 16 64 40 06
 | 
			
		||||
W: 16 00 0A 01 00 00 17 DF 00 00 17 F3 00 00 3A 36 FD 91 00 25 30 01 00 EF 05 11 05 01 00 00 10 01 00 3C 00 50 3C 00
 | 
			
		||||
W: 16 64 43 06
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 02 00 00 64 3C 00 20 03 E8 00 00 04 10 68 FE D5 FB 95 00 02 00 14 03 E8 01 00 01 F4 00 1E 00 3C 0E 10 00
 | 
			
		||||
W: 16 64 05 08
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 03 00 00 0A 46 05 32 01 0F 01 F4 00 64 46 50 0A 0D 0C 0C C0 01 90 00 64 19 00 01 00 14 00 01 00 14 03 23
 | 
			
		||||
W: 16 64 E0 04
 | 
			
		||||
W: 16 00 0A 03 00 00 0A 46 05 32 01 0F 01 F4 00 64 46 50 0A 0E D8 0E 99 01 90 00 64 19 00 01 00 14 00 01 00 14 03 23
 | 
			
		||||
W: 16 64 88 05
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 04 00 00 07 08 25 5A 32 0F 64 60 00 A0 0B B8 00 C8 28 01 F4 00 00 00 00 00 00 00 00 00 00 43 80 04 00 00
 | 
			
		||||
W: 16 64 B0 05
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 05 00 00 0F 00 2A 04 0A 7D 00 00 01 0A FE 76 E7 54 00 28 03 E8 02 01 2C F0 00 04 18 0D 5B 0D 28 0D 02 0D
 | 
			
		||||
W: 16 64 94 06
 | 
			
		||||
W: 16 00 0A 05 00 00 0F 00 2A 04 0A 7D 00 00 01 0A FE 76 E7 54 00 28 03 E8 02 01 2C F0 00 01 07 10 63 10 48 10 2D 10
 | 
			
		||||
W: 16 64 DF 06
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 06 00 00 0A 0D 06 0D 06 0D 07 0D 06 0D 05 0D 04 0D 04 0D 03 0D 08 0D 04 0C F9 0C ED 0C EC 0C E0 0C DA 0C
 | 
			
		||||
W: 16 64 A5 05
 | 
			
		||||
W: 16 00 0A 06 00 00 15 0F FC 0F E6 0F D0 0F BC 0F A8 0F 96 0F 84 0F 74 0F 65 0F 56 0F 45 0F 30 0F 1C 0F 09 0E F9 0E
 | 
			
		||||
W: 16 64 05 09
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 07 00 00 D6 0C D7 0C DA 0C D9 0C D9 0C D8 0C D5 0C D2 0C D2 0C D0 0C C9 0C BE 0C B4 0C A7 0C 9A 0C 8A 0C
 | 
			
		||||
W: 16 64 31 0D
 | 
			
		||||
W: 16 00 0A 07 00 00 EF 0E E6 0E DF 0E D8 0E D3 0E CF 0E CB 0E CA 0E C9 0E C7 0E C2 0E B8 0E AC 0E 9A 0E 85 0E 7B 0E
 | 
			
		||||
W: 16 64 04 0D
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 08 00 00 85 0C 7E 0C 2D 0B 64 09 64 FD 9E 03 6B 05 37 00 58 01 FA 01 D6 01 17 01 50 01 94 01 E2 01 CE 02
 | 
			
		||||
W: 16 64 57 09
 | 
			
		||||
W: 16 00 0A 08 00 00 75 0E 56 0E 30 0D AB 0A 69 FF 2B FF 41 FF 56 FF 61 FF 67 FF 3B FF 16 FF 21 FF 21 FE EB FE B5 FE
 | 
			
		||||
W: 16 64 02 12
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 09 00 00 62 FF 67 01 99 03 7D 05 9C 00 DA 02 CB 03 AD 04 A1 04 72 02 F1 03 A0 03 85 03 E7 04 86 04 EE 02
 | 
			
		||||
W: 16 64 8E 0B
 | 
			
		||||
W: 16 00 0A 09 00 00 7F FE 5E FE 7F FE E8 00 02 00 9A 00 2E FF E2 FF CD FF B7 FF A1 FF 77 FF 36 FE DA FE 62 FC F3 FA
 | 
			
		||||
W: 16 64 EA 15
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 0A 00 00 AB 01 0C FE D1 FE EE FF 28 FF 76 FF 51 00 13 00 88 FE 42 FD 29 05 9B 23 48 FF 7E FF 8B FF 6C FF
 | 
			
		||||
W: 16 64 F0 11
 | 
			
		||||
W: 16 00 0A 0A 00 00 B3 F8 ED F7 7C F7 3B F7 B2 F7 FC F8 32 F8 F7 F9 F0 F9 B0 F9 18 EC 9D 4D C0 FF 65 FF AC FF 98 FF
 | 
			
		||||
W: 16 64 E4 18
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 0B 00 00 46 FF 97 FF 8D FF 97 FF 98 FF 84 FF 8C FF AB FF B1 FF B1 FF 92 FF 74 FF 35 FF 0B FF 06 FF 5E FF
 | 
			
		||||
W: 16 64 65 17
 | 
			
		||||
W: 16 00 0A 0B 00 00 75 FF BB FF 82 FF 93 FF BB FF D5 FF E4 FF CE FF AD 00 80 FF 73 00 00 FF 16 FE EC FE ED FE DC FE
 | 
			
		||||
W: 16 64 F5 17
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 0C 00 00 13 FF 17 FF 10 FE C7 FE D8 FF 0C FF 05 FE E3 FF 2E FF 1D FE B7 00 00 01 C2 00 32 FF CE 02 26 64
 | 
			
		||||
W: 16 64 25 11
 | 
			
		||||
W: 16 00 0A 0C 00 00 F3 FF 09 FE F7 FE AC FE 9E FE C6 FE DA FE DC FE 8E FF 75 00 00 00 00 01 C2 00 32 FF CE 02 26 64
 | 
			
		||||
W: 16 64 10 13
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 0D 00 00 7B 1F BE 77 60 7E 00 00 00 00 64 00 19 00 64 28 63 5F 64 62 00 64 00 1E 00 B4 00 64 00 F0 00 FA
 | 
			
		||||
W: 16 64 D9 08
 | 
			
		||||
W: 16 00 0A 0D 00 00 7B 20 00 00 60 7E 00 00 00 00 64 00 19 00 64 28 63 5F 64 62 00 64 00 1E 00 B4 00 64 00 F0 00 FA
 | 
			
		||||
W: 16 64 A5 07
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 0E 00 00 11 10 10 68 49 FA 18 37 09 18 00 04 00 14 00 00 0A F0 00 0A 05 00 32 01 C2 14 14 00 00 3C 00 4B
 | 
			
		||||
W: 16 64 29 05
 | 
			
		||||
W: 16 00 0A 0E 00 00 11 10 10 68 41 D9 AF 37 00 00 00 01 00 14 00 00 0A F0 00 0A 05 00 32 01 C2 14 14 00 00 3C 00 4B
 | 
			
		||||
W: 16 64 73 05
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 0F 00 00 00 28 00 3C 3C 01 90 36 72 04 14 FF FF FF FF 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10 04
 | 
			
		||||
W: 16 64 02 0E
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 10 00 00 01 75 FE 79 08 1E FF 83 7F FF 00 AF 00 04 0A 64 01 00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00
 | 
			
		||||
W: 16 64 8B 06
 | 
			
		||||
W: 16 00 0A 10 00 00 01 2C 00 C8 00 00 00 00 00 A0 00 AF 00 00 0A 64 01 00 3C 00 00 00 00 00 00 00 00 00 00 00 00 00
 | 
			
		||||
W: 16 64 09 03
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 | 
			
		||||
W: 16 64 1B 00
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 12 00 00 02 26 02 01 F4 02 58 02 02 26 0E 00 00 00 00 00 00 00 00 00 00 00 00 17 00 DC 84 E5 5F 60 1C 0E
 | 
			
		||||
W: 16 64 12 05
 | 
			
		||||
W: 16 00 0A 12 00 00 02 26 02 01 F4 02 58 02 02 26 0E 00 00 00 00 00 00 00 00 00 00 00 00 01 00 DC 84 E5 5F 00 00 0E
 | 
			
		||||
W: 16 64 80 04
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 13 00 00 10 00 21 00 01 00 01 03 E8 64 17 70 64 00 FE 70 10 68 10 68 10 04 0A 32 1E 00 0A 2D 37 01 01 03
 | 
			
		||||
W: 16 64 C9 05
 | 
			
		||||
W: 16 00 0A 13 00 00 10 00 00 00 01 00 00 03 84 64 03 E8 15 18 FE 70 10 68 10 68 10 04 0A 32 1E 00 0A 2D 37 01 01 01
 | 
			
		||||
W: 16 64 6E 05
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 14 00 00 0B 62 71 33 34 7A 31 30 30 2D 47 31 0B 54 65 78 61 73 20 49 6E 73 74 2E 04 4C 49 46 4F 00 96 00
 | 
			
		||||
W: 16 64 D3 08
 | 
			
		||||
W: 16 00 0A 14 00 00 0B 62 71 33 34 7A 31 30 30 2D 47 31 0B 54 65 78 61 73 20 49 6E 73 74 2E 04 4C 49 4F 4E 00 96 00
 | 
			
		||||
W: 16 64 DB 08
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 15 00 00 AF 00 4B 00 64 0A F0 02 0B 54 10 CC 02 10 68 64 01 03 05 00 00 00 00 00 00 00 00 00 00 00 00 00
 | 
			
		||||
@@ -138,31 +138,31 @@ W: 16 00 0A 17 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
 | 
			
		||||
W: 16 64 01 20
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 18 00 00 FF 55 00 1A 00 1C 00 23 00 35 00 1E 00 20 00 27 00 22 00 25 00 42 00 3F 00 41 00 76 00 9D 02 0A
 | 
			
		||||
W: 16 64 91 04
 | 
			
		||||
W: 16 00 0A 18 00 00 FF 55 00 69 00 64 00 71 00 8F 00 62 00 61 00 6C 00 59 00 56 00 55 00 57 00 5A 00 6E 02 87 05 DC
 | 
			
		||||
W: 16 64 FF 07
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 19 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 | 
			
		||||
W: 16 64 23 00
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 1A 00 00 FF FF 00 1A 00 1C 00 23 00 35 00 1E 00 20 00 27 00 22 00 25 00 42 00 3F 00 41 00 76 00 9D 02 0A
 | 
			
		||||
W: 16 64 3D 05
 | 
			
		||||
W: 16 00 0A 1A 00 00 FF FF 00 69 00 64 00 71 00 8F 00 62 00 61 00 6C 00 59 00 56 00 55 00 57 00 5A 00 6E 02 87 05 DC
 | 
			
		||||
W: 16 64 AB 08
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 1B 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 | 
			
		||||
W: 16 64 25 00
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 1C 00 00 11 10 10 68 49 FA 18 37 09 18 00 04 00 14 00 00 0A F0 00 0A 05 00 32 01 C2 14 14 00 00 3C 00 4B
 | 
			
		||||
W: 16 64 37 05
 | 
			
		||||
W: 16 00 0A 1C 00 00 64 3C 00 20 03 E8 00 00 04 10 68 FE D5 FB 95 00 02 00 14 03 E8 01 00 01 F4 00 1E 00 3C 0E 10 00
 | 
			
		||||
W: 16 64 1F 08
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 1D 00 00 00 28 00 3C 3C 01 90 36 72 04 14 FF FF FF FF 01 23 45 67 89 AB CD EF FE DC BA 98 76 54 32 10 04
 | 
			
		||||
W: 16 64 10 0E
 | 
			
		||||
W: 16 00 0A 1D 00 00 0A 46 05 32 01 0F 01 F4 00 64 46 50 0A 0E D8 0E 99 01 90 00 64 19 00 01 00 14 00 01 00 14 03 23
 | 
			
		||||
W: 16 64 A2 05
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
W: 16 00 0A 1E 00 00 FF FF FF FF 00 00 02 6B FF FF FD 93 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
 | 
			
		||||
W: 16 00 0A 1E 00 00 FF FF FF FF 00 00 00 01 FF FF FF FD FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
 | 
			
		||||
W: 16 64 0B 1C
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
@@ -174,7 +174,7 @@ W: 16 00 08
 | 
			
		||||
W: 16 64 08 00
 | 
			
		||||
X: 2
 | 
			
		||||
C: 16 66 00
 | 
			
		||||
C: 16 04 F1 4C
 | 
			
		||||
C: 16 04 5B 67
 | 
			
		||||
W: 16 00 05
 | 
			
		||||
W: 16 64 05 00
 | 
			
		||||
X: 170
 | 
			
		||||
 
 | 
			
		||||
@@ -70,7 +70,7 @@ impl Default for Plant {
 | 
			
		||||
            pump_hour_start: 8,
 | 
			
		||||
            pump_hour_end: 20,
 | 
			
		||||
            mode: Mode::OFF,
 | 
			
		||||
            sensor_b: false
 | 
			
		||||
            sensor_b: false,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,7 @@ enum WaitType {
 | 
			
		||||
    FlashError,
 | 
			
		||||
    NormalConfig,
 | 
			
		||||
    StayAlive,
 | 
			
		||||
    StayAliveBtn
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Default)]
 | 
			
		||||
@@ -227,28 +228,41 @@ fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
 | 
			
		||||
    println!("cur is {}", cur);
 | 
			
		||||
 | 
			
		||||
    let mut to_config = false;
 | 
			
		||||
    if board.is_config_reset() {
 | 
			
		||||
        board.general_fault(true);
 | 
			
		||||
        println!("Reset config is pressed, waiting 5s");
 | 
			
		||||
        for _i in 0..25 {
 | 
			
		||||
        for _i in 0..5 {
 | 
			
		||||
            board.general_fault(true);
 | 
			
		||||
            Delay::new_default().delay_ms(50);
 | 
			
		||||
            Delay::new_default().delay_ms(100);
 | 
			
		||||
            board.general_fault(false);
 | 
			
		||||
            Delay::new_default().delay_ms(50);
 | 
			
		||||
            Delay::new_default().delay_ms(100);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if board.is_config_reset() {
 | 
			
		||||
            println!("Reset config is still pressed, deleting configs and reboot");
 | 
			
		||||
            match board.remove_configs() {
 | 
			
		||||
                Ok(case) => {
 | 
			
		||||
                    println!("Succeeded in deleting config {}", case);
 | 
			
		||||
            to_config = true;
 | 
			
		||||
            println!("Reset config is still pressed, proceed to config mode");
 | 
			
		||||
            for _i in 0..25 {
 | 
			
		||||
                board.general_fault(true);
 | 
			
		||||
                Delay::new_default().delay_ms(25);
 | 
			
		||||
                board.general_fault(false);
 | 
			
		||||
                Delay::new_default().delay_ms(25);
 | 
			
		||||
            }
 | 
			
		||||
            if board.is_config_reset() {
 | 
			
		||||
                println!("Reset config is still pressed, proceed to delete configs");
 | 
			
		||||
                match board.remove_configs() {
 | 
			
		||||
                    Ok(case) => {
 | 
			
		||||
                        println!("Succeeded in deleting config {}", case);
 | 
			
		||||
                    }
 | 
			
		||||
                    Err(err) => {
 | 
			
		||||
                        println!("Could not remove config files, system borked {}", err);
 | 
			
		||||
                        //terminate main app and freeze
 | 
			
		||||
    
 | 
			
		||||
                        wait_infinity(WaitType::FlashError, Arc::new(AtomicBool::new(false)));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Err(err) => {
 | 
			
		||||
                    println!("Could not remove config files, system borked {}", err);
 | 
			
		||||
                    //terminate main app and freeze
 | 
			
		||||
            } else {
 | 
			
		||||
 | 
			
		||||
                    wait_infinity(WaitType::FlashError, Arc::new(AtomicBool::new(false)));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            board.general_fault(false);
 | 
			
		||||
@@ -310,7 +324,7 @@ fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
    println!("Running logic at europe/berlin {}", europe_time);
 | 
			
		||||
 | 
			
		||||
    let config: Config;
 | 
			
		||||
    match board.get_config() {
 | 
			
		||||
    match board.get_config()  {
 | 
			
		||||
        Ok(valid) => {
 | 
			
		||||
            config = valid;
 | 
			
		||||
        }
 | 
			
		||||
@@ -422,7 +436,9 @@ fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
        &mut board,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    let stay_alive = STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed);
 | 
			
		||||
    
 | 
			
		||||
    let stay_alive_mqtt = STAY_ALIVE.load(std::sync::atomic::Ordering::Relaxed);
 | 
			
		||||
    let stay_alive = stay_alive_mqtt;
 | 
			
		||||
    println!("Check stay alive, current state is {}", stay_alive);
 | 
			
		||||
 | 
			
		||||
    let mut did_pump = false;
 | 
			
		||||
@@ -442,7 +458,7 @@ fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
                "Trying to pump for {}s with pump {} now",
 | 
			
		||||
                plant_config.pump_time_s, plant
 | 
			
		||||
            );
 | 
			
		||||
            if !stay_alive {
 | 
			
		||||
            if !stay_alive && !to_config {
 | 
			
		||||
                did_pump = true;
 | 
			
		||||
                board.any_pump(true)?;
 | 
			
		||||
                board.store_last_pump_time(plant, cur);
 | 
			
		||||
@@ -552,7 +568,15 @@ fn safe_main() -> anyhow::Result<()> {
 | 
			
		||||
    //is deep sleep
 | 
			
		||||
    mark_app_valid();
 | 
			
		||||
 | 
			
		||||
    if to_config {
 | 
			
		||||
        println!("Go to button triggerd stay alive");
 | 
			
		||||
        drop(board);
 | 
			
		||||
        let reboot_now = Arc::new(AtomicBool::new(false));
 | 
			
		||||
        let _webserver = httpd(reboot_now.clone());
 | 
			
		||||
        wait_infinity(WaitType::StayAliveBtn, reboot_now.clone());
 | 
			
		||||
    }
 | 
			
		||||
    if stay_alive {
 | 
			
		||||
        println!("Go to stay alive move");
 | 
			
		||||
        drop(board);
 | 
			
		||||
        let reboot_now = Arc::new(AtomicBool::new(false));
 | 
			
		||||
        let _webserver = httpd(reboot_now.clone());
 | 
			
		||||
@@ -926,12 +950,14 @@ fn wait_infinity(wait_type: WaitType, reboot_now: Arc<AtomicBool>) -> ! {
 | 
			
		||||
        WaitType::FlashError => 100_u32,
 | 
			
		||||
        WaitType::NormalConfig => 500_u32,
 | 
			
		||||
        WaitType::StayAlive => 1000_u32,
 | 
			
		||||
        WaitType::StayAliveBtn => 25_u32
 | 
			
		||||
    };
 | 
			
		||||
    let led_count = match wait_type {
 | 
			
		||||
        WaitType::InitialConfig => 8,
 | 
			
		||||
        WaitType::FlashError => 8,
 | 
			
		||||
        WaitType::NormalConfig => 4,
 | 
			
		||||
        WaitType::StayAlive => 2,
 | 
			
		||||
        WaitType::StayAliveBtn => 5
 | 
			
		||||
    };
 | 
			
		||||
    loop {
 | 
			
		||||
        unsafe {
 | 
			
		||||
 
 | 
			
		||||
@@ -191,7 +191,7 @@ pub trait PlantCtrlBoardInteraction {
 | 
			
		||||
    fn mqtt_publish(&mut self, config: &Config, subtopic: &str, message: &[u8]) -> Result<()>;
 | 
			
		||||
 | 
			
		||||
    fn sensor_multiplexer(&mut self, n: u8) -> Result<()>;
 | 
			
		||||
    fn flash_bq34_z100(&mut self, line: &str, dryrun:bool) -> Result<()>;              
 | 
			
		||||
    fn flash_bq34_z100(&mut self, line: &str, dryrun: bool) -> Result<()>;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub trait CreatePlantHal<'a> {
 | 
			
		||||
@@ -206,7 +206,8 @@ pub struct PlantCtrlBoard<'a> {
 | 
			
		||||
        PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>,
 | 
			
		||||
        PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, InputOutput>,
 | 
			
		||||
    >,
 | 
			
		||||
    shift_register_enable_invert: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Output>,
 | 
			
		||||
    shift_register_enable_invert:
 | 
			
		||||
        PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Output>,
 | 
			
		||||
    tank_channel: AdcChannelDriver<'a, Gpio5, AdcDriver<'a, esp_idf_hal::adc::ADC1>>,
 | 
			
		||||
    solar_is_day: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>,
 | 
			
		||||
    boot_button: PinDriver<'a, esp_idf_hal::gpio::AnyIOPin, esp_idf_hal::gpio::Input>,
 | 
			
		||||
@@ -359,7 +360,7 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
 | 
			
		||||
            5 => FAULT_6,
 | 
			
		||||
            6 => FAULT_7,
 | 
			
		||||
            7 => FAULT_8,
 | 
			
		||||
            _ => panic!("Invalid plant id {}", plant)
 | 
			
		||||
            _ => panic!("Invalid plant id {}", plant),
 | 
			
		||||
        };
 | 
			
		||||
        self.shift_register.decompose()[index]
 | 
			
		||||
            .set_state(enable.into())
 | 
			
		||||
@@ -413,7 +414,7 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
 | 
			
		||||
                5 => SENSOR_A_6,
 | 
			
		||||
                6 => SENSOR_A_7,
 | 
			
		||||
                7 => SENSOR_A_8,
 | 
			
		||||
                _ => bail!("Invalid plant id {}", plant)
 | 
			
		||||
                _ => bail!("Invalid plant id {}", plant),
 | 
			
		||||
            },
 | 
			
		||||
            Sensor::B => match plant {
 | 
			
		||||
                0 => SENSOR_B_1,
 | 
			
		||||
@@ -424,52 +425,45 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
 | 
			
		||||
                5 => SENSOR_B_6,
 | 
			
		||||
                6 => SENSOR_B_7,
 | 
			
		||||
                7 => SENSOR_B_8,
 | 
			
		||||
                _ => bail!("Invalid plant id {}", plant)
 | 
			
		||||
                _ => bail!("Invalid plant id {}", plant),
 | 
			
		||||
            },
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        let mut results = [0;REPEAT_MOIST_MEASURE];
 | 
			
		||||
        let mut results = [0; REPEAT_MOIST_MEASURE];
 | 
			
		||||
        for repeat in 0..REPEAT_MOIST_MEASURE {
 | 
			
		||||
            self.signal_counter.counter_pause()?;
 | 
			
		||||
            self.signal_counter.counter_clear()?;
 | 
			
		||||
            //Disable all
 | 
			
		||||
            self.shift_register.decompose()[MS_4]
 | 
			
		||||
            self.shift_register.decompose()[MS_4].set_high().unwrap();
 | 
			
		||||
 | 
			
		||||
            self.sensor_multiplexer(sensor_channel)?;
 | 
			
		||||
 | 
			
		||||
            self.shift_register.decompose()[MS_4].set_low().unwrap();
 | 
			
		||||
            self.shift_register.decompose()[SENSOR_ON]
 | 
			
		||||
                .set_high()
 | 
			
		||||
                .unwrap();
 | 
			
		||||
        
 | 
			
		||||
            self.sensor_multiplexer(sensor_channel)?;
 | 
			
		||||
    
 | 
			
		||||
            self.shift_register.decompose()[MS_4]
 | 
			
		||||
                .set_low()
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            self.shift_register.decompose()[SENSOR_ON]  
 | 
			
		||||
            .set_high()
 | 
			
		||||
            .unwrap();
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            let delay = Delay::new_default();
 | 
			
		||||
            let measurement = 10;
 | 
			
		||||
            let factor = 1000 as f32 / measurement as f32;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
            //give some time to stabilize
 | 
			
		||||
            delay.delay_ms(10);
 | 
			
		||||
            self.signal_counter.counter_resume()?;
 | 
			
		||||
            delay.delay_ms(measurement);
 | 
			
		||||
            self.signal_counter.counter_pause()?;
 | 
			
		||||
            self.shift_register.decompose()[MS_4]
 | 
			
		||||
                .set_high()
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            self.shift_register.decompose()[MS_4].set_high().unwrap();
 | 
			
		||||
            self.shift_register.decompose()[SENSOR_ON]
 | 
			
		||||
            .set_low()
 | 
			
		||||
            .unwrap();
 | 
			
		||||
            delay.delay_ms(10); 
 | 
			
		||||
                .set_low()
 | 
			
		||||
                .unwrap();
 | 
			
		||||
            delay.delay_ms(10);
 | 
			
		||||
            let unscaled = self.signal_counter.get_counter_value()? as i32;
 | 
			
		||||
            let hz = (unscaled as f32 * factor) as i32;
 | 
			
		||||
            results[repeat] = hz;
 | 
			
		||||
            //println!("Measuring {:?} @ {} with {}", sensor, plant, hz);
 | 
			
		||||
        }
 | 
			
		||||
        results.sort();
 | 
			
		||||
       
 | 
			
		||||
 | 
			
		||||
        let mid = results.len() / 2;
 | 
			
		||||
 | 
			
		||||
        Ok(results[mid])
 | 
			
		||||
@@ -693,7 +687,7 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
 | 
			
		||||
        for plant in 0..PLANT_COUNT {
 | 
			
		||||
            let a = self.measure_moisture_hz(plant, plant_hal::Sensor::A);
 | 
			
		||||
            let b = self.measure_moisture_hz(plant, plant_hal::Sensor::B);
 | 
			
		||||
            print!("P:{} a:{:?} b:{:?}", plant, a ,b)
 | 
			
		||||
            print!("P:{} a:{:?} b:{:?}", plant, a, b)
 | 
			
		||||
        }
 | 
			
		||||
        println!();
 | 
			
		||||
        Delay::new_default().delay_ms(10);
 | 
			
		||||
@@ -1006,7 +1000,7 @@ impl PlantCtrlBoardInteraction for PlantCtrlBoard<'_> {
 | 
			
		||||
        }
 | 
			
		||||
        Ok(())
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    fn flash_bq34_z100(&mut self, line: &str, dryrun: bool) -> Result<()> {
 | 
			
		||||
        match &mut self.battery_driver {
 | 
			
		||||
            Some(driver) => match driver.write_flash_stream_i2c(line, dryrun) {
 | 
			
		||||
@@ -1127,10 +1121,10 @@ impl CreatePlantHal<'_> for PlantHal {
 | 
			
		||||
        ms2.set_low()?;
 | 
			
		||||
        let ms3 = &mut shift_register.decompose()[MS_3];
 | 
			
		||||
        ms3.set_low()?;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        let ms4 = &mut shift_register.decompose()[MS_4];
 | 
			
		||||
        ms4.set_high()?;
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        //init,reset rtc memory depending on cause
 | 
			
		||||
        let reasons = ResetReason::get();
 | 
			
		||||
        let reset_store = match reasons {
 | 
			
		||||
@@ -1255,7 +1249,6 @@ impl CreatePlantHal<'_> for PlantHal {
 | 
			
		||||
            println!("Managed to comunnicate with battery");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        
 | 
			
		||||
        let shift_register_enable_invert = PinDriver::output(peripherals.pins.gpio21.downgrade())?;
 | 
			
		||||
 | 
			
		||||
        let rv = Mutex::new(PlantCtrlBoard {
 | 
			
		||||
@@ -1276,14 +1269,13 @@ impl CreatePlantHal<'_> for PlantHal {
 | 
			
		||||
            battery_driver: Some(battery_driver),
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let _ = rv.lock().is_ok_and(|mut board|{
 | 
			
		||||
            unsafe { gpio_hold_dis(board.shift_register_enable_invert.pin())};
 | 
			
		||||
            board.shift_register_enable_invert.set_low().unwrap();        
 | 
			
		||||
            unsafe { gpio_hold_en(board.shift_register_enable_invert.pin())}; 
 | 
			
		||||
        let _ = rv.lock().is_ok_and(|mut board| {
 | 
			
		||||
            unsafe { gpio_hold_dis(board.shift_register_enable_invert.pin()) };
 | 
			
		||||
            board.shift_register_enable_invert.set_low().unwrap();
 | 
			
		||||
            unsafe { gpio_hold_en(board.shift_register_enable_invert.pin()) };
 | 
			
		||||
            return true;
 | 
			
		||||
        });
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
        Ok(rv)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,8 +18,15 @@
 | 
			
		||||
  </form>
 | 
			
		||||
 | 
			
		||||
  <h2>Battery Firmeware (bq34z100 may be R2)</h2>
 | 
			
		||||
  <button id="flash5ah12vlifepo">Flash 6AH 12V Lifepo replacement (built in)</button>
 | 
			
		||||
  <div style="height: 100px; display: block; overflow-y: auto;" id = "flash_message"></div>
 | 
			
		||||
  <form id="upload_form" method="post">
 | 
			
		||||
    <input type="file" name="battery_flash_file" id="battery_flash_file"><br>
 | 
			
		||||
    <progress id="progressBar" value="0" max="100" style="width:300px;"></progress>
 | 
			
		||||
    <input type="button" name="battery_flash_button" id="battery_flash_button"><br>
 | 
			
		||||
    <h3 id="status"></h3>
 | 
			
		||||
    <div style="height: 100px; display: block; overflow-y: auto;" id = "battery_flash_message"></div>
 | 
			
		||||
  </form>
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  <h2>config</h2>
 | 
			
		||||
 | 
			
		||||
  <div id="configform">
 | 
			
		||||
 
 | 
			
		||||
@@ -17,6 +17,16 @@
 | 
			
		||||
            </form>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <h2>Battery Firmeware (bq34z100 may be R2)</h2>
 | 
			
		||||
        <form id="upload_form" method="post">
 | 
			
		||||
          <input type="file" name="battery_flash_file" id="battery_flash_file"><br>
 | 
			
		||||
          <progress id="battery_flash_progressBar" value="0" max="100" style="width:300px;"></progress>
 | 
			
		||||
          <input type="button" name="battery_flash_button" id="battery_flash_button"><br>
 | 
			
		||||
          <h3 id="battery_flash_status"></h3>
 | 
			
		||||
          <p id="battery_flash_loaded_n_total"></p>
 | 
			
		||||
          <div style="height: 100px; display: block; overflow-y: auto;" id = "battery_flash_message"></div>
 | 
			
		||||
        </form>
 | 
			
		||||
 | 
			
		||||
        <div>
 | 
			
		||||
            <h2>WIFI</h2>
 | 
			
		||||
            <input type="button" id="scan" value="Scan">
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,18 @@
 | 
			
		||||
//offer ota and config mode
 | 
			
		||||
 | 
			
		||||
use std::{
 | 
			
		||||
    io::BufRead, str::from_utf8, sync::{atomic::AtomicBool, Arc}
 | 
			
		||||
    collections::VecDeque,
 | 
			
		||||
    io::{BufRead, Read, Write},
 | 
			
		||||
    str::from_utf8,
 | 
			
		||||
    sync::{atomic::AtomicBool, Arc},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
use crate::{espota::OtaUpdate, BOARD_ACCESS};
 | 
			
		||||
use core::result::Result::Ok;
 | 
			
		||||
use embedded_svc::http::Method;
 | 
			
		||||
use esp_idf_hal::{delay::Delay, io::Write};
 | 
			
		||||
use embedded_svc::http::{Method};
 | 
			
		||||
use esp_idf_hal::delay::Delay;
 | 
			
		||||
use esp_idf_svc::http::server::{Configuration, EspHttpServer};
 | 
			
		||||
use esp_idf_sys::vTaskDelay;
 | 
			
		||||
use heapless::String;
 | 
			
		||||
use serde::{Deserialize, Serialize};
 | 
			
		||||
 | 
			
		||||
@@ -289,46 +293,82 @@ pub fn shared() -> Box<EspHttpServer<'static>> {
 | 
			
		||||
        })
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    server
 | 
			
		||||
    .fn_handler("/flashbattery", Method::Post, move |request| {
 | 
			
		||||
        let mut board = BOARD_ACCESS.lock().unwrap();
 | 
			
		||||
        let mut response = request.into_ok_response().unwrap();
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        .fn_handler("/flashbattery", Method::Post, move |mut request| {
 | 
			
		||||
            let mut board = BOARD_ACCESS.lock().unwrap();
 | 
			
		||||
            let mut buffer: [u8; 32] = [0; 32];
 | 
			
		||||
            let mut line_buffer: VecDeque<u8> = VecDeque::new();
 | 
			
		||||
 | 
			
		||||
        let delay = Delay::new(0);
 | 
			
		||||
        let firmware = include_bytes!("0100_2_02-bq34z100.df.fs");
 | 
			
		||||
            let is_dry_run = !request.uri().ends_with("?flash=true");
 | 
			
		||||
            let mut total_read: usize = 0;
 | 
			
		||||
 | 
			
		||||
        response.write("Checking pass: \n".as_bytes()).unwrap();
 | 
			
		||||
        for iter in firmware.lines() {
 | 
			
		||||
            delay.delay_us(1);
 | 
			
		||||
            let line = iter?;
 | 
			
		||||
            let msg = format!("{line}<br>");
 | 
			
		||||
            println!("{line}");
 | 
			
		||||
            response.write(msg.as_bytes()).unwrap();
 | 
			
		||||
            let validate = board.flash_bq34_z100(&line, true);
 | 
			
		||||
            if validate.is_err() {
 | 
			
		||||
                response.write(validate.unwrap_err().to_string().as_bytes()).unwrap();
 | 
			
		||||
            let mut toggle = true;
 | 
			
		||||
            let delay = Delay::new(1);
 | 
			
		||||
            loop {
 | 
			
		||||
                delay.delay_us(2);
 | 
			
		||||
                let read = request.read(&mut buffer).unwrap();
 | 
			
		||||
                total_read += read;
 | 
			
		||||
                println!("received {read} bytes ota {total_read}");
 | 
			
		||||
                if read == 0 {
 | 
			
		||||
                    if line_buffer.len() > 0 {
 | 
			
		||||
                        println!("No further body but no endline");
 | 
			
		||||
                        let mut line = std::string::String::new();
 | 
			
		||||
                        line_buffer.read_to_string(&mut line).unwrap();
 | 
			
		||||
                        let msg = format!("Finished reading, but there is still some leftover in buffer and no full line {line}<br>");
 | 
			
		||||
                        println!("{}", msg);
 | 
			
		||||
                        let mut response = request.into_status_response(400_u16).unwrap();          
 | 
			
		||||
                        response.write(msg.as_bytes()).unwrap();
 | 
			
		||||
                        response.flush().unwrap();
 | 
			
		||||
                        return anyhow::Ok(())
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                let to_write = &buffer[0..read];
 | 
			
		||||
                line_buffer.write_all(to_write).unwrap();
 | 
			
		||||
                println!("Write to deque new lenght is {}", line_buffer.len());
 | 
			
		||||
                board.general_fault(toggle);
 | 
			
		||||
                toggle = !toggle;
 | 
			
		||||
                println!("Updated btn");
 | 
			
		||||
                
 | 
			
		||||
                loop {
 | 
			
		||||
                    let mut line = std::string::String::new();
 | 
			
		||||
                    println!("Check for line");
 | 
			
		||||
                    let has_line = line_buffer.read_line(&mut line);
 | 
			
		||||
                    let mut line_size = 0;
 | 
			
		||||
                    match has_line {
 | 
			
		||||
                        Ok(size) => {
 | 
			
		||||
                            line_size = size;
 | 
			
		||||
                            if size == 0 {
 | 
			
		||||
                                println!("Was no line no string read");
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        },
 | 
			
		||||
                        Err(err) => {
 | 
			
		||||
                            println!("Was no line and error {}", err);
 | 
			
		||||
                            break;
 | 
			
		||||
                        },
 | 
			
		||||
                    }
 | 
			
		||||
                    println!("Processing line with size {} {}", line_size, line);
 | 
			
		||||
                    //let validate = board.flash_bq34_z100(&line, is_dry_run);
 | 
			
		||||
                    let validate = anyhow::Ok(());
 | 
			
		||||
                    delay.delay_us(2);
 | 
			
		||||
                    if validate.is_err() {
 | 
			
		||||
                        let mut response = request.into_status_response(400_u16).unwrap();          
 | 
			
		||||
                        let err = validate.unwrap_err();
 | 
			
		||||
                        let err_str = err.to_string();
 | 
			
		||||
                        let err_msg = err_str.as_bytes();
 | 
			
		||||
                        response
 | 
			
		||||
                            .write(err_msg)
 | 
			
		||||
                            .unwrap();
 | 
			
		||||
                        return anyhow::Ok(())
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        response.write("Executing flashing: \n".as_bytes()).unwrap();
 | 
			
		||||
        let mut toggle = true;
 | 
			
		||||
        for iter in firmware.lines() {
 | 
			
		||||
            delay.delay_us(1);
 | 
			
		||||
            let line = iter?;
 | 
			
		||||
            let msg = format!("{line}<br>");
 | 
			
		||||
            println!("{line}");
 | 
			
		||||
            let mut response = request.into_status_response(200_u16).unwrap();          
 | 
			
		||||
            let msg = format!("Finished writing {total_read} bytes<br>");
 | 
			
		||||
            response.write(msg.as_bytes()).unwrap();
 | 
			
		||||
            board.general_fault(toggle);
 | 
			
		||||
            toggle = !toggle;
 | 
			
		||||
            let write = board.flash_bq34_z100(&line, false);
 | 
			
		||||
            if write.is_err() {
 | 
			
		||||
                response.write(write.unwrap_err().to_string().as_bytes()).unwrap();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        board.general_fault(false);
 | 
			
		||||
        anyhow::Ok(())
 | 
			
		||||
    })
 | 
			
		||||
    .unwrap();
 | 
			
		||||
            board.general_fault(false);
 | 
			
		||||
            anyhow::Ok(())
 | 
			
		||||
        })
 | 
			
		||||
        .unwrap();
 | 
			
		||||
    server
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,33 @@
 | 
			
		||||
interface FirmeWareFlashRequest{
 | 
			
		||||
    name: string
 | 
			
		||||
  }
 | 
			
		||||
let battery_flash_button = document.getElementById("battery_flash_button") as HTMLButtonElement;
 | 
			
		||||
let battery_flash_file = document.getElementById("battery_flash_file") as HTMLInputElement;
 | 
			
		||||
let battery_flash_message = document.getElementById("battery_flash_message") as HTMLElement;
 | 
			
		||||
let battery_flash_progressBar = document.getElementById("battery_flash_progressBar") as HTMLProgressElement;
 | 
			
		||||
 | 
			
		||||
let flash5ah12vlifepo = document.getElementById("flash5ah12vlifepo") as HTMLButtonElement;
 | 
			
		||||
 | 
			
		||||
let flash_message = document.getElementById("flash_message") as HTMLElement;
 | 
			
		||||
var ajax = new XMLHttpRequest();
 | 
			
		||||
 | 
			
		||||
ajax.upload.addEventListener("progress", event => {
 | 
			
		||||
  loaded_n_total.innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
 | 
			
		||||
  var percent = (event.loaded / event.total) * 100;
 | 
			
		||||
  progressBar.value = Math.round(percent);
 | 
			
		||||
  status.innerHTML = Math.round(percent) + "%";
 | 
			
		||||
  answer.innerHTML = "in progress";
 | 
			
		||||
}, false);
 | 
			
		||||
ajax.addEventListener("load", () => {
 | 
			
		||||
  status.innerHTML = ajax.responseText;
 | 
			
		||||
  answer.innerHTML = "finished";
 | 
			
		||||
  progressBar.value = 0;
 | 
			
		||||
}, false);
 | 
			
		||||
ajax.addEventListener("error", () => {
 | 
			
		||||
  status.innerHTML = ajax.responseText;
 | 
			
		||||
  answer.innerHTML = "failed";
 | 
			
		||||
}, false);
 | 
			
		||||
ajax.addEventListener("abort", () => {
 | 
			
		||||
  status.innerHTML = ajax.responseText;
 | 
			
		||||
  answer.innerHTML = "aborted";
 | 
			
		||||
}, false);
 | 
			
		||||
ajax.open("POST", "/ota");
 | 
			
		||||
ajax.send(file);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<string> {
 | 
			
		||||
@@ -17,24 +39,21 @@ export async function streamToText(stream: ReadableStream<Uint8Array>): Promise<
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
      result += value;
 | 
			
		||||
      flash_message.innerHTML = result;
 | 
			
		||||
      flash_message.scrollTop = flash_message.scrollHeight;
 | 
			
		||||
 | 
			
		||||
      battery_flash_message.innerHTML = result;
 | 
			
		||||
      battery_flash_message.scrollTop = battery_flash_message.scrollHeight;
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
flash5ah12vlifepo.onclick = async function (){
 | 
			
		||||
    var body:FirmeWareFlashRequest = {
 | 
			
		||||
      name: "flash5ah12vlifepo"
 | 
			
		||||
    } 
 | 
			
		||||
 | 
			
		||||
    var pretty = JSON.stringify(body, undefined, 1);
 | 
			
		||||
    fetch("/flashbattery", {
 | 
			
		||||
      method :"POST",
 | 
			
		||||
      body: pretty
 | 
			
		||||
    }).then((response) => response.body)
 | 
			
		||||
    .then((body) => {
 | 
			
		||||
      streamToText(body)
 | 
			
		||||
    });
 | 
			
		||||
};
 | 
			
		||||
battery_flash_button.onclick = async function (){
 | 
			
		||||
  fetch("/flashbattery", {
 | 
			
		||||
    method :"POST",
 | 
			
		||||
    body: battery_flash_file.files[0],
 | 
			
		||||
    headers: {
 | 
			
		||||
      "Content-Type": ""
 | 
			
		||||
    },
 | 
			
		||||
  }).then((response) => response.body)
 | 
			
		||||
  .then((body) => {
 | 
			
		||||
    streamToText(body)
 | 
			
		||||
  });
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user