[sw][matcha] Fix cam_i2c_test failure

* Select frame end bit
* Trim the frame in 320x240 mode

Bug: 310074028

Change-Id: I9b1e51ccdafd3683b4c55e32d3e179e071cd0900
diff --git a/sw/device/lib/dif/dif_isp_wrapper.c b/sw/device/lib/dif/dif_isp_wrapper.c
index 280b0a7..8768533 100644
--- a/sw/device/lib/dif/dif_isp_wrapper.c
+++ b/sw/device/lib/dif/dif_isp_wrapper.c
@@ -197,8 +197,9 @@
 // ISP confituration: live, raw and bypass modes
 // Input arguments are frame weight, frame height and Y,Cb,Cr written addresses.
 dif_result_t _dif_isp_wrapper_set_raw_byp_en(
-    const dif_isp_wrapper_t *isp_wrapper, const uint32_t frame_width,
-    uint32_t frame_height,
+    const dif_isp_wrapper_t *isp_wrapper, const uint32_t frame_h_size,
+    const uint32_t frame_v_size, const uint32_t frame_h_offs,
+    const uint32_t frame_v_offs,
     // TODO(ykwang): put these variables into a config variable.
     const uint32_t y_base_ad_init_addr, const uint32_t cb_base_ad_init_addr,
     const uint32_t cr_base_ad_init_addr, const uint32_t y_base_ad_init2_addr,
@@ -212,10 +213,10 @@
   mmio_region_write32(isp_wrapper->base_addr, VI_CCL, 0x00000002);
   mmio_region_write32(isp_wrapper->base_addr, VI_ICCL, 0x00000059);
   mmio_region_write32(isp_wrapper->base_addr, VI_IRCL, 0x00000000);
-  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_H_OFFS, 0x00000000);
-  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_V_OFFS, 0x00000000);
-  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_H_SIZE, frame_width);
-  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_V_SIZE, frame_height);
+  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_H_OFFS, frame_h_offs);
+  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_V_OFFS, frame_v_offs);
+  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_H_SIZE, frame_h_size);
+  mmio_region_write32(isp_wrapper->base_addr, ISP_ACQ_V_SIZE, frame_v_size);
   mmio_region_write32(isp_wrapper->base_addr, ISP_TPG_TOTAL_IN, 0x011d8518);
   mmio_region_write32(isp_wrapper->base_addr, ISP_TPG_ACT_IN, 0x00a001e0);
   mmio_region_write32(isp_wrapper->base_addr, ISP_TPG_FP_IN, 0x001c8126);
@@ -227,8 +228,8 @@
   mmio_region_write32(isp_wrapper->base_addr, ISP_TPG_FRAME_NUM, 0x00000003);
   mmio_region_write32(isp_wrapper->base_addr, ISP_OUT_H_OFFS, 0x00000000);
   mmio_region_write32(isp_wrapper->base_addr, ISP_OUT_V_OFFS, 0x00000000);
-  mmio_region_write32(isp_wrapper->base_addr, ISP_OUT_H_SIZE, frame_width);
-  mmio_region_write32(isp_wrapper->base_addr, ISP_OUT_V_SIZE, frame_height);
+  mmio_region_write32(isp_wrapper->base_addr, ISP_OUT_H_SIZE, frame_h_size);
+  mmio_region_write32(isp_wrapper->base_addr, ISP_OUT_V_SIZE, frame_v_size);
   mmio_region_write32(isp_wrapper->base_addr, ISP_BLS_CTRL, 0x00000000);
   mmio_region_write32(isp_wrapper->base_addr, ISP_BLS_A_FIXED, 0x00000000);
   mmio_region_write32(isp_wrapper->base_addr, ISP_BLS_B_FIXED, 0x00000000);
@@ -313,7 +314,7 @@
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_BASE_AD_INIT,
                       y_base_ad_init_addr);
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_SIZE_INIT,
-                      frame_width * frame_height);
+                      frame_h_size * frame_v_size);
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_OFFS_CNT_INIT, 0x00000000);
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_IRQ_OFFS_INIT, 0x00000000);
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_CB_BASE_AD_INIT,
@@ -332,14 +333,14 @@
                       cb_base_ad_init2_addr);
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_CR_BASE_AD_INIT2,
                       cr_base_ad_init2_addr);
-  mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_LLENGTH, frame_width);
+  mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_LLENGTH, frame_h_size);
   mmio_region_write32(isp_wrapper->base_addr, MI_OUTPUT_ALIGN_FORMAT,
                       0x00000401);
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_OUTPUT_FIFO_SIZE, 0x00000000);
-  mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_PIC_WIDTH, frame_width);
-  mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_PIC_HEIGHT, frame_height);
+  mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_PIC_WIDTH, frame_h_size);
+  mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_PIC_HEIGHT, frame_v_size);
   mmio_region_write32(isp_wrapper->base_addr, MI_MP_Y_PIC_SIZE,
-                      frame_width * frame_height);
+                      frame_h_size * frame_v_size);
   mmio_region_write32(isp_wrapper->base_addr, SRSZ_CTRL, 0x000001c0);
   mmio_region_write32(isp_wrapper->base_addr, SRSZ_SCALE_HY, 0x0000546d);
   mmio_region_write32(isp_wrapper->base_addr, SRSZ_SCALE_HCB, 0x0000db23);
@@ -389,27 +390,27 @@
 // raw:320x240, byp:320x240
 dif_result_t dif_isp_wrapper_set_raw_320x240_byp_320x240_en(
     const dif_isp_wrapper_t *isp_wrapper) {
-  return _dif_isp_wrapper_set_raw_byp_en(isp_wrapper, 0x140, 0xf0, 0x5a000000,
-                                         0x5a01a000, 0x5a01a000, 0x5a020000,
-                                         0x5a03a000, 0x5a03a000);
+  return _dif_isp_wrapper_set_raw_byp_en(isp_wrapper, 0x140, 0xf0, 0x2, 0x2,
+                                         0x5a000000, 0x5a01a000, 0x5a01a000,
+                                         0x5a020000, 0x5a03a000, 0x5a03a000);
 }
 
 // ISP configuration:
 // raw:320x240, byp:320x240, hps image address: 0x00300000
 dif_result_t dif_isp_wrapper_set_ml_mem_byp_320x240_en(
     const dif_isp_wrapper_t *isp_wrapper) {
-  return _dif_isp_wrapper_set_raw_byp_en(isp_wrapper, 0x140, 0xf0, 0x5a300000,
-                                         0x5a320000, 0x5a320000, 0x5a340000,
-                                         0x5a360000, 0x5a360000);
+  return _dif_isp_wrapper_set_raw_byp_en(isp_wrapper, 0x140, 0xf0, 0x2, 0x2,
+                                         0x5a300000, 0x5a320000, 0x5a320000,
+                                         0x5a340000, 0x5a360000, 0x5a360000);
 }
 
 // ISP configuration:
 // raw:324x324, byp:324x324
 dif_result_t dif_isp_wrapper_set_raw_324x324_byp_324x324_en(
     const dif_isp_wrapper_t *isp_wrapper) {
-  return _dif_isp_wrapper_set_raw_byp_en(isp_wrapper, 0x144, 0x144, 0x5a000000,
-                                         0x5a01a000, 0x5a01a000, 0x5a034000,
-                                         0x5a04e000, 0x5a04e000);
+  return _dif_isp_wrapper_set_raw_byp_en(isp_wrapper, 0x144, 0x144, 0x0, 0x0,
+                                         0x5a000000, 0x5a01a000, 0x5a01a000,
+                                         0x5a034000, 0x5a04e000, 0x5a04e000);
 }
 
 dif_result_t dif_isp_wrapper_clear_en(const dif_isp_wrapper_t *isp_wrapper) {
diff --git a/sw/device/tests/smc/smc_cam_i2c_test.c b/sw/device/tests/smc/smc_cam_i2c_test.c
index 64d27d2..e31bcb8 100644
--- a/sw/device/tests/smc/smc_cam_i2c_test.c
+++ b/sw/device/tests/smc/smc_cam_i2c_test.c
@@ -40,6 +40,27 @@
 
 static volatile bool isp_frame_done_irq_seen = false;
 
+static void handle_isp_wrapper_isrs(const dif_rv_plic_irq_id_t interrupt_id) {
+  // NOTE: This initialization is superfluous, since the `default` case below
+  // is effectively noreturn, but the compiler is unable to prove this.
+  const uint32_t mp_frame_end_mask = 0x1;
+  uint32_t mi_mis;
+  switch (interrupt_id) {
+    case kTopMatchaPlicIrqIdIspWrapperIsp:
+      CHECK_DIF_OK(dif_isp_wrapper_isp_irq_done(&isp_wrapper));
+      break;
+    case kTopMatchaPlicIrqIdIspWrapperMi:
+      CHECK_DIF_OK(dif_isp_wrapper_read_mi_mis(&isp_wrapper, &mi_mis));
+      if (mi_mis & mp_frame_end_mask) {
+        isp_frame_done_irq_seen = true;
+      }
+      CHECK_DIF_OK(dif_isp_wrapper_mi_irq_done(&isp_wrapper));
+      break;
+    default:
+      LOG_FATAL("ISR is not implemented!");
+  }
+}
+
 void ottf_external_isr(void) {
   dif_rv_plic_irq_id_t interrupt_id;
   CHECK_DIF_OK(dif_rv_plic_irq_claim(&plic, kTopMatchaPlicTargetIbex0Smc,
@@ -56,17 +77,7 @@
       break;
     }
     case kTopMatchaPlicPeripheralIspWrapper: {
-      uint32_t mi_mis, isp_mis;
-      CHECK_DIF_OK(dif_isp_wrapper_read_mi_mis(&isp_wrapper, &mi_mis));
-      CHECK_DIF_OK(dif_isp_wrapper_read_isp_mis(&isp_wrapper, &isp_mis));
-      CHECK_DIF_OK(dif_isp_wrapper_write_isp_icr(&isp_wrapper, isp_mis));
-      CHECK_DIF_OK(dif_isp_wrapper_write_mi_icr(&isp_wrapper, mi_mis));
-      CHECK_DIF_OK(dif_isp_wrapper_irq_acknowledge_all(&isp_wrapper));
-
-      if (isp_mis & (1 << 5)) {
-        isp_frame_done_irq_seen = true;
-      }
-
+      handle_isp_wrapper_isrs(interrupt_id);
       break;
     }
     default:
@@ -91,16 +102,18 @@
 
   // Configure interrupts for camera and ISP.
   CHECK_DIF_OK(camera_hm01b0_irq_init(&plic, kTopMatchaPlicTargetIbex0Smc));
+  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
+      &plic, kTopMatchaPlicIrqIdIspWrapperIsp, kDifRvPlicMaxPriority));
+  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
+      &plic, kTopMatchaPlicIrqIdIspWrapperMi, kDifRvPlicMaxPriority));
+  CHECK_DIF_OK(dif_rv_plic_target_set_threshold(
+      &plic, kTopMatchaPlicTargetIbex0Smc, kDifRvPlicMinPriority));
   CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
       &plic, kTopMatchaPlicIrqIdIspWrapperIsp, kTopMatchaPlicTargetIbex0Smc,
       kDifToggleEnabled));
   CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
       &plic, kTopMatchaPlicIrqIdIspWrapperMi, kTopMatchaPlicTargetIbex0Smc,
       kDifToggleEnabled));
-  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
-      &plic, kTopMatchaPlicIrqIdIspWrapperIsp, kDifRvPlicMaxPriority));
-  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
-      &plic, kTopMatchaPlicIrqIdIspWrapperMi, kDifRvPlicMaxPriority));
   irq_global_ctrl(true);
   irq_external_ctrl(true);