Hi guys,
I use a _global_reg var in my program to avoid save/load:
_global_var uint32_t finished_pixels;
this variable is updated in ADC interrupt.
In main, I have following code:
register uint32_t processed_pixels = 0;
finished_pixels = 0; // Initial global reg
while (processed_pixels >= finished_pixels)
{
// Process new pixel
...
}
But the armcc will optimize all code in while loop, i.e, "// Process new pixel" section.
I tried "volatile _global_var uint32_t finished_pixels;", but the compiler says it has no effect and the same thing happens;
Now I use "volatile register uint32_t processed_pixels = 0;" to avoid the trap, but it looks ugly.
Is that a compile bug?
Any bettrer solutions?
Thanks a lot!
Sorry daith, I made a mistake. As you said, on pixel takes up to 0.25us.
I use a sub pixel algorithm to accumulate pixel values and location weighted pixel values:
note: val_sum is a global uint32_t and weighted_sum is a uint64_t var.
the assembly code uses lots save/load as following:
ADC1_2_IRQHandler PROC
;;;787
;;;788 void ADC1_2_IRQHandler(void)
000254 b4c0 PUSH {r6,r7}
;;;789 {
;;;790 /* Test on ADC end of conversion interrupt */
;;;791 // if(ADC_GetITStatus(ADC1, ADC_IT_EOC))
;;;792 {
;;;793 register uint32_t val;
;;;794
;;;795 #if USE_INTERPOLATION
;;;796 register uint32_t interpolation;
;;;797 #endif
;;;798
;;;799 /* Clear ADC end of conversion interrupt -- 读取ADC1->DR时自动清除 */
;;;800 // ADC_ClearITPendingBit(ADC1, ADC_IT_EOC)
;;;801
;;;802 /* ADC value */
;;;803 val = ADC1->DR;
000256 f04f40a0 MOV r0,#0x50000000
00025a 6c00 LDR r0,[r0,#0x40]
;;;804
;;;805 #if USE_INTERPOLATION
;;;806 interpolation = (prev_val + val) >> 1;
;;;807 prev_val = val;
;;;808
;;;809 interpolation *= interpolation;
;;;810 val_sum += interpolation;
;;;811 curr_pixel++;
00025c 1c64 ADDS r4,r4,#1
00025e 1829 ADDS r1,r5,r0 ;806
000260 0849 LSRS r1,r1,#1 ;806
000262 fb01f201 MUL r2,r1,r1 ;809
000266 4912 LDR r1,|L1.688|
000268 4605 MOV r5,r0 ;807
00026a 68cb LDR r3,[r1,#0xc] ;810 ; val_sum
;;;812 weighted_sum += interpolation * curr_pixel;
00026c e9d1c704 LDRD r12,r7,[r1,#0x10]
000270 189e ADDS r6,r3,r2 ;810
000272 fb02f304 MUL r3,r2,r4
000276 2200 MOVS r2,#0
000278 eb130c0c ADDS r12,r3,r12
00027c eb420307 ADC r3,r2,r7
;;;813 #endif
;;;814
;;;815 val *= val;
000280 4368 MULS r0,r5,r0
;;;816 val_sum += val;
000282 4406 ADD r6,r6,r0
;;;817 curr_pixel++;
000284 1c64 ADDS r4,r4,#1
;;;818 weighted_sum += val * curr_pixel;
000286 4360 MULS r0,r4,r0
000288 eb10000c ADDS r0,r0,r12
00028c 415a ADCS r2,r2,r3
00028e 60ce STR r6,[r1,#0xc] ; val_sum
;;;819
;;;820 #if USE_INTERPOLATION
;;;821 if (curr_pixel >= (PIXEL_CNT << 1))
000290 e9c10204 STRD r0,r2,[r1,#0x10]
000294 f5b46f00 CMP r4,#0x800
;;;822 #else
;;;823 if (curr_pixel >= PIXEL_CNT)
;;;824 #endif
;;;825 {
;;;826 /* 已采集足够像素,关掉ADC中断 */
;;;827 ADC_ITConfig(ADC1, ADC_IT_EOC, DISABLE);
;;;828 }
;;;829 }
;;;830 }
000298 bf3c ITT CC
00029a bcc0 POPCC {r6,r7}
00029c 4770 BXCC lr
00029e 2200 MOVS r2,#0 ;827
0002a0 bcc0 POP {r6,r7} ;827
0002a2 2104 MOVS r1,#4 ;827
0002a4 f04f40a0 MOV r0,#0x50000000 ;827
0002a8 f7ffbffe B.W ADC_ITConfig
;;;831
ENDP
For a STM32F302CBT6@72MHZ, only 93M/s*0.25us=23 single cycle instructions allowed.
Also. the row pixel values should be send to UART in calibrate mode.
So I tried get data in ADC interrupt & process data in main loop/calibrate loop to avoid save/load.
Could you give me further suggestion?
Thanks.