Serial TX/RX builder
This commit is contained in:
144
tests/test_serial_pseudocode.py
Normal file
144
tests/test_serial_pseudocode.py
Normal file
@@ -0,0 +1,144 @@
|
||||
import json
|
||||
import tempfile
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from h8536.serial_pseudocode import (
|
||||
SerialPseudocodeOptions,
|
||||
generate_serial_pseudocode,
|
||||
write_serial_pseudocode,
|
||||
)
|
||||
|
||||
|
||||
def candidate_payload() -> dict:
|
||||
return {
|
||||
"instructions": [],
|
||||
"sci_protocol": {
|
||||
"manual_references": [
|
||||
"Manual/0900766b802125d0.md:15794 RDR receive data register",
|
||||
"Manual/0900766b802125d0.md:15823 TDR transmit data register",
|
||||
],
|
||||
},
|
||||
"board_profile": {
|
||||
"summary": "Board trace ties the H8/536 SCI1 pins to a MAX202 RS232 transceiver.",
|
||||
"manual_references": [
|
||||
"Manual/0900766b802125d0.md:2417 FP-80 H8/536 pin 66 is P95/TXD",
|
||||
],
|
||||
"traces": [
|
||||
{
|
||||
"signal": "TXD",
|
||||
"h8_pin": 66,
|
||||
"h8_pin_name": "P95/TXD",
|
||||
"max202_pin": 11,
|
||||
"evidence": "MAX202 pin 11 traces to H8 pin 66",
|
||||
},
|
||||
{
|
||||
"signal": "RXD",
|
||||
"h8_pin": 67,
|
||||
"h8_pin_name": "P96/RXD",
|
||||
"max202_pin": 12,
|
||||
"evidence": "MAX202 pin 12 traces to H8 pin 67",
|
||||
},
|
||||
],
|
||||
},
|
||||
"serial_reconstruction": {
|
||||
"candidates": [
|
||||
{
|
||||
"kind": "candidate_sci1_tx_frame",
|
||||
"channel": "SCI1",
|
||||
"frame_length": 6,
|
||||
"buffer_start": 0xF858,
|
||||
"buffer_start_hex": "H'F858",
|
||||
"buffer_end": 0xF85D,
|
||||
"buffer_end_hex": "H'F85D",
|
||||
"checksum_address": 0xF85D,
|
||||
"tx_index_address": 0xF9C2,
|
||||
"tdr_address": 0xFEDB,
|
||||
"checksum_seed": 0x5A,
|
||||
"checksum_formula": "checksum = 0x5A ^ byte0 ^ byte1 ^ byte2 ^ byte3 ^ byte4",
|
||||
"confidence": "high",
|
||||
"confidence_score": 0.95,
|
||||
"confidence_reason": "all required independent evidence groups were observed",
|
||||
"comment": "candidate/evidence-supported SCI1 6-byte TX frame hypothesis",
|
||||
"evidence_addresses_hex": {
|
||||
"tx_checksum_seed": ["H'BA4E"],
|
||||
"xor_checksum_chain": ["H'BA50", "H'BA54"],
|
||||
},
|
||||
},
|
||||
{
|
||||
"kind": "candidate_sci1_rx_frame",
|
||||
"channel": "SCI1",
|
||||
"frame_length": 6,
|
||||
"capture_buffer_start": 0xF868,
|
||||
"capture_buffer_start_hex": "H'F868",
|
||||
"capture_buffer_end": 0xF86D,
|
||||
"capture_buffer_end_hex": "H'F86D",
|
||||
"validation_buffer_start": 0xF860,
|
||||
"validation_buffer_end": 0xF865,
|
||||
"checksum_address": 0xF865,
|
||||
"rx_index_address": 0xF9C3,
|
||||
"rdr_address": 0xFEDD,
|
||||
"interbyte_timeout_address": 0xF9C1,
|
||||
"complete_timer_address": 0xF9C5,
|
||||
"checksum_seed": 0x5A,
|
||||
"checksum_formula": "checksum = 0x5A ^ byte0 ^ byte1 ^ byte2 ^ byte3 ^ byte4",
|
||||
"confidence": "high",
|
||||
"confidence_score": 0.9,
|
||||
"confidence_reason": "RX count, copy, and checksum-validation evidence were observed",
|
||||
"caveat": "candidate frame means six consecutive bytes, not a proven delimited packet",
|
||||
"comment": "candidate/evidence-supported SCI1 6-byte RX frame hypothesis",
|
||||
"evidence_addresses_hex": {
|
||||
"rx_rdr_read": ["H'BB6D"],
|
||||
"rx_xor_checksum_validation": ["H'BBD6", "H'BBEC"],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class SerialPseudocodeTest(unittest.TestCase):
|
||||
def test_generates_focused_tx_and_rx_candidate_paths(self):
|
||||
text = generate_serial_pseudocode(candidate_payload(), source_name="rom.json")
|
||||
|
||||
self.assertIn("focused SCI RX/TX pseudocode from rom.json", text)
|
||||
self.assertIn("SCI1 TX 6-byte frame at H'F858-H'F85D", text)
|
||||
self.assertIn("SCI1 RX 6-byte frame captured at H'F868-H'F86D", text)
|
||||
self.assertIn("MAX202 pin 11 traces to H8 pin 66", text)
|
||||
self.assertIn("Manual/0900766b802125d0.md:15823 TDR transmit data register", text)
|
||||
self.assertIn("#define TX_FRAME(n) MEM8[(u16)(0xF858u + (n))]", text)
|
||||
self.assertIn("#define RX_CAPTURE(n) MEM8[(u16)(0xF868u + (n))]", text)
|
||||
self.assertIn("checksum ^= TX_FRAME(4);", text)
|
||||
self.assertIn("TX_FRAME(5) = sci1_tx_candidate_checksum();", text)
|
||||
self.assertIn("SCI1_TDR = TX_FRAME(0);", text)
|
||||
self.assertIn("void sci1_txi_candidate_isr(void)", text)
|
||||
self.assertIn("SCI1_SSR &= (u8)~SCI_SSR_RDRF;\n byte = SCI1_RDR;", text)
|
||||
self.assertIn("RX_CAPTURE(RX_INDEX) = byte;", text)
|
||||
self.assertIn("return sci1_process_rx_candidate_frame();", text)
|
||||
self.assertIn("rx_xor_checksum_validation: H'BBD6, H'BBEC", text)
|
||||
|
||||
def test_tx_only_option_omits_rx_functions(self):
|
||||
text = generate_serial_pseudocode(
|
||||
candidate_payload(),
|
||||
options=SerialPseudocodeOptions(include_rx=False),
|
||||
)
|
||||
|
||||
self.assertIn("void sci1_tx_start_candidate_frame(void)", text)
|
||||
self.assertNotIn("sci1_rx_byte_received_candidate_isr", text)
|
||||
|
||||
def test_write_serial_pseudocode_writes_output_file(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
input_path = Path(tmp) / "rom.json"
|
||||
output_path = Path(tmp) / "serial.c"
|
||||
input_path.write_text(
|
||||
json.dumps(candidate_payload()),
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
write_serial_pseudocode(input_path, output_path, SerialPseudocodeOptions())
|
||||
|
||||
self.assertIn("sci1_process_rx_candidate_frame", output_path.read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user