ArDrone SDK 1.8 added
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VLIB / Platform / arm9 / video_dct_p5p.c
diff --git a/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VLIB/Platform/arm9/video_dct_p5p.c b/mardrone/ARDrone_SDK_Version_1_8_20110726/ARDroneLib/VLIB/Platform/arm9/video_dct_p5p.c
new file mode 100644 (file)
index 0000000..d22987f
--- /dev/null
@@ -0,0 +1,254 @@
+#include <cyg/io/io.h>
+#include <cyg/hal/hal_io.h>         // I/O macros
+#include <cyg/hal/drv_api.h>        // cyg_interrupt
+#include <cyg/hal/hal_platform_ints.h>
+#include <cyg/kernel/diag.h>
+
+#include "video_config.h"
+#include "video_dct_p5p.h"
+#include "video_utils_p5p.h"
+
+#if (MAX_NUM_MACRO_BLOCKS_PER_CALL > 10)
+# error "MAX_NUM_MACRO_BLOCKS_PER_CALL must not be greater than 10 on P5P"
+#endif
+
+#if (VIDEO_DCT_USE_INTRAM == 0)
+#include <cyg/utils/mmu.h>
+#endif
+
+static cyg_uint32 dct_in_progress;
+
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
+
+static cyg_interrupt dct_interrupt;
+static cyg_handle_t dct_interrupt_handle;
+
+//! DCT driver interrupt service routine (ISR)
+static cyg_uint32 dct_isr( cyg_vector_t vector, cyg_addrword_t data )
+{
+  cyg_drv_interrupt_mask(vector);
+  cyg_drv_interrupt_acknowledge(vector);
+
+  return CYG_ISR_CALL_DSR;  // request DSR
+}
+
+//! DCT driver deffered service routine (DSR)
+static void dct_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+  cyg_uint32 itack;
+
+  RTMON_USTOP( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
+
+  switch( dct_read_reg( DCT_STATUS ) )
+  {
+    case DCT_STATUS_END_OK:
+      itack = DCT_ITACK_END_OK;
+      break;
+
+    case DCT_STATUS_ERROR:
+      diag_printf("[DCT] DMA access failure\n");
+      itack = DCT_ITACK_ERROR;
+      break;
+
+    default:
+      itack = 0;
+      break;
+  }
+
+  dct_write_reg( DCT_ITACK,  itack );
+
+  cyg_drv_interrupt_unmask(vector);
+}
+#endif // VIDEO_DCT_INTERRUPT_ENABLE
+
+
+C_RESULT video_dct_p5p_init(void)
+{
+  cyg_uint32 value;
+
+  HAL_READ_UINT32( PARROT5_SYS + _SYS_CEN, value);
+  HAL_WRITE_UINT32( PARROT5_SYS + _SYS_CEN, (value | SYS_CEN_CAMIFCLK) );
+
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
+  diag_printf("Configuring DCT with interrupt acknowledge\n");
+  cyg_drv_interrupt_create( CYGNUM_HAL_INTERRUPT_DCT,
+                            1,
+                            (cyg_addrword_t) 0,
+                            dct_isr,
+                            dct_dsr,
+                            &dct_interrupt_handle,
+                            &dct_interrupt );
+
+  cyg_drv_interrupt_attach(dct_interrupt_handle);
+
+  cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DCT);
+
+  dct_write_reg( DCT_ITEN , DCT_ITEN_END_OK | DCT_ITEN_ERROR );
+#else
+  dct_write_reg ( DCT_ITEN,  0 );
+#endif // VIDEO_DCT_INTERRUPT_ENABLE
+
+  dct_in_progress = 0;
+
+  return C_OK;
+}
+
+#ifdef HAS_FDCT_COMPUTE
+
+int16_t* video_fdct_compute(int16_t* in, int16_t* out, int32_t num_macro_blocks)
+{
+  cyg_uint32  ctrl = 0;
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 0)
+  cyg_uint32  itack = 0;
+#endif
+
+  num_macro_blocks *= 6;
+
+#if (VIDEO_DCT_USE_INTRAM == 0)
+//   arm_mmu_clean_dcache_range((CYG_ADDRESS)in, num_macro_blocks*MCU_BLOCK_SIZE*2 );
+//   arm_mmu_invalidate_cache_range((CYG_ADDRESS)in, num_macro_blocks*MCU_BLOCK_SIZE*2 );
+//
+//   arm_mmu_clean_dcache_range((CYG_ADDRESS)out, num_macro_blocks*MCU_BLOCK_SIZE*2 );
+//   arm_mmu_invalidate_cache_range((CYG_ADDRESS)out, num_macro_blocks*MCU_BLOCK_SIZE*2 );
+
+  arm_mmu_flush_dcache();
+#endif
+
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
+  cyg_drv_dsr_lock();
+#else
+
+  if( dct_in_progress > 0 )
+  {
+    RTMON_USTART( VIDEO_VLIB_DCT_WAIT_UEVENT );
+
+    // Check if we have to wait for a previous run to complete
+    while( dct_read_reg( DCT_STATUS ) == 0 );
+
+    RTMON_USTOP( VIDEO_VLIB_DCT_WAIT_UEVENT );
+  }
+
+  switch( dct_read_reg( DCT_STATUS ) )
+  {
+    case DCT_STATUS_END_OK:
+      // diag_printf("DCT_STATUS_END_OK\n");
+      itack = DCT_ITACK_END_OK;
+      break;
+
+    case DCT_STATUS_ERROR:
+      diag_printf("[DCT] DMA access failure\n");
+      itack = DCT_ITACK_ERROR;
+      break;
+
+    default:
+      itack = 0;
+      break;
+  }
+
+  if( itack > 0 )
+    dct_write_reg( DCT_ITACK,  itack ); // Acknowledge previous run
+
+#endif // VIDEO_DCT_INTERRUPT_ENABLE
+
+  ctrl |= ((num_macro_blocks - 1) & 0x3F ) << 1;
+  ctrl |= DCT_CTRLMODE_FDCT;
+
+  dct_write_reg ( DCT_ORIG_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)in ) );
+  dct_write_reg ( DCT_ORIG_CU_ADDR, 0 );
+  dct_write_reg ( DCT_ORIG_CV_ADDR, 0 );
+
+  dct_write_reg ( DCT_DEST_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)out ) );
+  dct_write_reg ( DCT_DEST_CU_ADDR, 0 );
+  dct_write_reg ( DCT_DEST_CV_ADDR, 0 );
+
+  dct_write_reg ( DCT_LINEOFFSET, 0 );
+
+  dct_write_reg ( DCT_CONTROL, ctrl );
+
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
+  cyg_drv_dsr_unlock();
+
+  RTMON_USTART( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
+#endif
+
+  dct_in_progress = 1;
+
+  return out + MCU_BLOCK_SIZE*num_macro_blocks;
+}
+
+#endif // HAS_FDCT_COMPUTE
+
+#ifdef HAS_IDCT_COMPUTE
+
+int16_t* video_idct_compute(int16_t* in, int16_t* out, int32_t num_macro_blocks)
+{
+  cyg_uint32  ctrl = 0;
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 0)
+  cyg_uint32  itack = 0;
+#endif
+
+#if (VIDEO_DCT_USE_INTRAM == 0)
+  arm_mmu_flush_dcache();
+#endif
+
+  num_macro_blocks *= 6;
+
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
+  cyg_drv_dsr_lock();
+#else
+
+  if( dct_in_progress > 0 )
+  {
+    // Check if we have to wait for a previous run to complete
+    while( dct_read_reg( DCT_STATUS ) == 0 );
+  }
+
+  switch( dct_read_reg( DCT_STATUS ) )
+  {
+    case DCT_STATUS_END_OK:
+      // diag_printf("DCT_STATUS_END_OK\n");
+      itack = DCT_ITACK_END_OK;
+      break;
+
+    case DCT_STATUS_ERROR:
+      diag_printf("[DCT] DMA access failure\n");
+      itack = DCT_ITACK_ERROR;
+      break;
+
+    default:
+      itack = 0;
+      break;
+  }
+
+  if( itack > 0 )
+    dct_write_reg( DCT_ITACK,  itack ); // Acknowledge previous run
+
+#endif // VIDEO_DCT_INTERRUPT_ENABLE
+
+  ctrl |= ((num_macro_blocks - 1) & 0x3F ) << 1;
+  ctrl |= DCT_CTRLMODE_IDCT;
+
+  dct_write_reg ( DCT_ORIG_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)in ) );
+  dct_write_reg ( DCT_ORIG_CU_ADDR, 0 );
+  dct_write_reg ( DCT_ORIG_CV_ADDR, 0 );
+
+  dct_write_reg ( DCT_DEST_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)out ) );
+  dct_write_reg ( DCT_DEST_CU_ADDR, 0 );
+  dct_write_reg ( DCT_DEST_CV_ADDR, 0 );
+
+  dct_write_reg ( DCT_LINEOFFSET, 0 );
+
+  dct_write_reg ( DCT_CONTROL, ctrl );
+
+#if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
+  cyg_drv_dsr_unlock();
+
+  RTMON_USTART( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
+#endif
+
+  dct_in_progress = 1;
+
+  return out + MCU_BLOCK_SIZE*num_macro_blocks;
+}
+
+#endif // HAS_IDCT_COMPUTE