d22987f0ca817955ca4f27db59affea2741b7129
[mardrone] / mardrone / ARDrone_SDK_Version_1_8_20110726 / ARDroneLib / VLIB / Platform / arm9 / video_dct_p5p.c
1 #include <cyg/io/io.h>
2 #include <cyg/hal/hal_io.h>         // I/O macros
3 #include <cyg/hal/drv_api.h>        // cyg_interrupt
4 #include <cyg/hal/hal_platform_ints.h>
5 #include <cyg/kernel/diag.h>
6
7 #include "video_config.h"
8 #include "video_dct_p5p.h"
9 #include "video_utils_p5p.h"
10
11 #if (MAX_NUM_MACRO_BLOCKS_PER_CALL > 10)
12 # error "MAX_NUM_MACRO_BLOCKS_PER_CALL must not be greater than 10 on P5P"
13 #endif
14
15 #if (VIDEO_DCT_USE_INTRAM == 0)
16 #include <cyg/utils/mmu.h>
17 #endif
18
19 static cyg_uint32 dct_in_progress;
20
21 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
22
23 static cyg_interrupt dct_interrupt;
24 static cyg_handle_t dct_interrupt_handle;
25
26 //! DCT driver interrupt service routine (ISR)
27 static cyg_uint32 dct_isr( cyg_vector_t vector, cyg_addrword_t data )
28 {
29   cyg_drv_interrupt_mask(vector);
30   cyg_drv_interrupt_acknowledge(vector);
31
32   return CYG_ISR_CALL_DSR;  // request DSR
33 }
34
35 //! DCT driver deffered service routine (DSR)
36 static void dct_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
37 {
38   cyg_uint32 itack;
39
40   RTMON_USTOP( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
41
42   switch( dct_read_reg( DCT_STATUS ) )
43   {
44     case DCT_STATUS_END_OK:
45       itack = DCT_ITACK_END_OK;
46       break;
47
48     case DCT_STATUS_ERROR:
49       diag_printf("[DCT] DMA access failure\n");
50       itack = DCT_ITACK_ERROR;
51       break;
52
53     default:
54       itack = 0;
55       break;
56   }
57
58   dct_write_reg( DCT_ITACK,  itack );
59
60   cyg_drv_interrupt_unmask(vector);
61 }
62 #endif // VIDEO_DCT_INTERRUPT_ENABLE
63
64
65 C_RESULT video_dct_p5p_init(void)
66 {
67   cyg_uint32 value;
68
69   HAL_READ_UINT32( PARROT5_SYS + _SYS_CEN, value);
70   HAL_WRITE_UINT32( PARROT5_SYS + _SYS_CEN, (value | SYS_CEN_CAMIFCLK) );
71
72 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
73   diag_printf("Configuring DCT with interrupt acknowledge\n");
74   cyg_drv_interrupt_create( CYGNUM_HAL_INTERRUPT_DCT,
75                             1,
76                             (cyg_addrword_t) 0,
77                             dct_isr,
78                             dct_dsr,
79                             &dct_interrupt_handle,
80                             &dct_interrupt );
81
82   cyg_drv_interrupt_attach(dct_interrupt_handle);
83
84   cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_DCT);
85
86   dct_write_reg( DCT_ITEN , DCT_ITEN_END_OK | DCT_ITEN_ERROR );
87 #else
88   dct_write_reg ( DCT_ITEN,  0 );
89 #endif // VIDEO_DCT_INTERRUPT_ENABLE
90
91   dct_in_progress = 0;
92
93   return C_OK;
94 }
95
96 #ifdef HAS_FDCT_COMPUTE
97
98 int16_t* video_fdct_compute(int16_t* in, int16_t* out, int32_t num_macro_blocks)
99 {
100   cyg_uint32  ctrl = 0;
101 #if (VIDEO_DCT_INTERRUPT_ENABLE == 0)
102   cyg_uint32  itack = 0;
103 #endif
104
105   num_macro_blocks *= 6;
106
107 #if (VIDEO_DCT_USE_INTRAM == 0)
108 //   arm_mmu_clean_dcache_range((CYG_ADDRESS)in, num_macro_blocks*MCU_BLOCK_SIZE*2 );
109 //   arm_mmu_invalidate_cache_range((CYG_ADDRESS)in, num_macro_blocks*MCU_BLOCK_SIZE*2 );
110 //
111 //   arm_mmu_clean_dcache_range((CYG_ADDRESS)out, num_macro_blocks*MCU_BLOCK_SIZE*2 );
112 //   arm_mmu_invalidate_cache_range((CYG_ADDRESS)out, num_macro_blocks*MCU_BLOCK_SIZE*2 );
113
114   arm_mmu_flush_dcache();
115 #endif
116
117 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
118   cyg_drv_dsr_lock();
119 #else
120
121   if( dct_in_progress > 0 )
122   {
123     RTMON_USTART( VIDEO_VLIB_DCT_WAIT_UEVENT );
124
125     // Check if we have to wait for a previous run to complete
126     while( dct_read_reg( DCT_STATUS ) == 0 );
127
128     RTMON_USTOP( VIDEO_VLIB_DCT_WAIT_UEVENT );
129   }
130
131   switch( dct_read_reg( DCT_STATUS ) )
132   {
133     case DCT_STATUS_END_OK:
134       // diag_printf("DCT_STATUS_END_OK\n");
135       itack = DCT_ITACK_END_OK;
136       break;
137
138     case DCT_STATUS_ERROR:
139       diag_printf("[DCT] DMA access failure\n");
140       itack = DCT_ITACK_ERROR;
141       break;
142
143     default:
144       itack = 0;
145       break;
146   }
147
148   if( itack > 0 )
149     dct_write_reg( DCT_ITACK,  itack ); // Acknowledge previous run
150
151 #endif // VIDEO_DCT_INTERRUPT_ENABLE
152
153   ctrl |= ((num_macro_blocks - 1) & 0x3F ) << 1;
154   ctrl |= DCT_CTRLMODE_FDCT;
155
156   dct_write_reg ( DCT_ORIG_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)in ) );
157   dct_write_reg ( DCT_ORIG_CU_ADDR, 0 );
158   dct_write_reg ( DCT_ORIG_CV_ADDR, 0 );
159
160   dct_write_reg ( DCT_DEST_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)out ) );
161   dct_write_reg ( DCT_DEST_CU_ADDR, 0 );
162   dct_write_reg ( DCT_DEST_CV_ADDR, 0 );
163
164   dct_write_reg ( DCT_LINEOFFSET, 0 );
165
166   dct_write_reg ( DCT_CONTROL, ctrl );
167
168 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
169   cyg_drv_dsr_unlock();
170
171   RTMON_USTART( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
172 #endif
173
174   dct_in_progress = 1;
175
176   return out + MCU_BLOCK_SIZE*num_macro_blocks;
177 }
178
179 #endif // HAS_FDCT_COMPUTE
180
181 #ifdef HAS_IDCT_COMPUTE
182
183 int16_t* video_idct_compute(int16_t* in, int16_t* out, int32_t num_macro_blocks)
184 {
185   cyg_uint32  ctrl = 0;
186 #if (VIDEO_DCT_INTERRUPT_ENABLE == 0)
187   cyg_uint32  itack = 0;
188 #endif
189
190 #if (VIDEO_DCT_USE_INTRAM == 0)
191   arm_mmu_flush_dcache();
192 #endif
193
194   num_macro_blocks *= 6;
195
196 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
197   cyg_drv_dsr_lock();
198 #else
199
200   if( dct_in_progress > 0 )
201   {
202     // Check if we have to wait for a previous run to complete
203     while( dct_read_reg( DCT_STATUS ) == 0 );
204   }
205
206   switch( dct_read_reg( DCT_STATUS ) )
207   {
208     case DCT_STATUS_END_OK:
209       // diag_printf("DCT_STATUS_END_OK\n");
210       itack = DCT_ITACK_END_OK;
211       break;
212
213     case DCT_STATUS_ERROR:
214       diag_printf("[DCT] DMA access failure\n");
215       itack = DCT_ITACK_ERROR;
216       break;
217
218     default:
219       itack = 0;
220       break;
221   }
222
223   if( itack > 0 )
224     dct_write_reg( DCT_ITACK,  itack ); // Acknowledge previous run
225
226 #endif // VIDEO_DCT_INTERRUPT_ENABLE
227
228   ctrl |= ((num_macro_blocks - 1) & 0x3F ) << 1;
229   ctrl |= DCT_CTRLMODE_IDCT;
230
231   dct_write_reg ( DCT_ORIG_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)in ) );
232   dct_write_reg ( DCT_ORIG_CU_ADDR, 0 );
233   dct_write_reg ( DCT_ORIG_CV_ADDR, 0 );
234
235   dct_write_reg ( DCT_DEST_Y_ADDR , arm_mmu_v2p( (cyg_addrword_t)out ) );
236   dct_write_reg ( DCT_DEST_CU_ADDR, 0 );
237   dct_write_reg ( DCT_DEST_CV_ADDR, 0 );
238
239   dct_write_reg ( DCT_LINEOFFSET, 0 );
240
241   dct_write_reg ( DCT_CONTROL, ctrl );
242
243 #if (VIDEO_DCT_INTERRUPT_ENABLE == 1)
244   cyg_drv_dsr_unlock();
245
246   RTMON_USTART( VIDEO_VLIB_DCT_COMPUTE_UEVENT );
247 #endif
248
249   dct_in_progress = 1;
250
251   return out + MCU_BLOCK_SIZE*num_macro_blocks;
252 }
253
254 #endif // HAS_IDCT_COMPUTE