102 6. REAL-TIME FILTERING
frq = [1:1:length(Y)];
subplot(3,1,3);
plot(frq*(fs/ns),Y);
grid on;
300
200
100
0
300
200
100
0
50
0
-50
-100
0
0 0.05 0.1 0.15 0.2 0.25 0.3 0.35 0.4 0.45 0.5
10.5 21.5 2.5
0 10.5 21.5 2.5
Frequency (Hz)
Frequency (Hz)
Magnitude (dB)Magnitude (dB)Magnitude (dB)
Frequency (pi rad/sample)
× 10
4
× 10
4
Figure L6.1: Synthesized signal.
L6.2 ARM OVERFLOW DETECTION
A method for detecting when an overflow occurs can be implemented by using ARM arithmetic
instructions which update the Application Program Status Register (APSR). By performing an
operation using the arithmetic instruction ADDS, the APSR can then be read to determine
L6. LAB 6: REAL-TIME FIR FILTERING, QUANTIZATION EFFECT, AND OVERFLOW 103
overflows. e following code shows an implementation of the ADDS instruction in ARM
assembly which uses this register.
#ifdef __arm__
.align 2
.global addStatus
addStatus:
@ r0 = input A and sum output address
@ r1 = input B and status output address
ldr r2, [r0] @ load contents at [r0] into r2
ldr r3, [r1] @ load contents at [r1] into r3
adds r2, r2, r3 @ add r2 and r3, store in r2
@ set status flags in APSR
mrs r3, APSR @ copy APSR to r3
str r2, [r0] @ store r2 at address [r0]
str r3, [r1] @ store r3 at address [r1]
bx lr @ return to caller
#elif __arm64__
.align 2
.global addStatus
addStatus:
@ x0 = input A and sum output address
@ x1 = input B and status output address
ldr w2, [x0] @ load contents at [x0] into w2
ldr w3, [x1] @ load contents at [x1] into w3
adds w2, w2, w3 @ add w2 and w3, store in w2
@ set status flags in APSR
mrs x3, NZCV @ copy APSR to x3
str w2, [x0] @ store w2 at address [x0]
str w3, [x1] @ store x3's MSB at address [r1]
ret
#endif
Since ARMv7 and ARMv8 instruction sets are used on different iOS devices, the assembly
code to check the APSR needs to be implemented properly for each instruction set. e line
#ifdef __arm__ checks at compile time if the supported instruction set is ARMv7. If the
instruction set is not ARMv7, it checks if the instructions set is ARMv8 using the __arm64__
flag. ere are some notable differences between the two implementations. ARMv8 uses 64-bit
registers, thus the register naming in the assembly code is different. On ARMv8, the register
file consists of 64-bit segments R0 through R30. When used in assembly coding, these registers
104 6. REAL-TIME FILTERING
must be further qualified to indicate the operand data size. Registers beginning with X refer
to full width 64-bit registers whereas registers beginning with W refer to 32-bit registers. Also,
note that the mnemonic for the status register is APSR on ARMv7 and NZCV on ARMv8.
e assembly code segment can then be called from C in the manner shown below.
static inline int
addGetStatus(short a, short b, short *c) {
//performs the operation a+b=c and returns the status register
int A = a << 16;
int B = b << 16;
addStatus(&A,&B);
(*c) = A >> 16;
return B;
}
After the execution of addGetStatus, the register A contains the status register and B contains
the result of the addition. e following test cases illustrate the operation of the addStatus func-
tion.
On an Android platform, __android_log_print is used to send the output to LogCat:
unsigned int status;
short result;
short A = 32767;
short B = 32767;
status = addGetStatus(A, B, &result);
__android_log_print(ANDROID_LOG_ERROR, "Add Status", "A: %d,
B: %d, C: %d, Status: %#010x", A, B, result, status);
A = 32767;
B = -32768;
status = addGetStatus(A, B, &result);
__android_log_print(ANDROID_LOG_ERROR, "Add Status", "A: %d,
B: %d, C: %d, Status: %#010x", A, B, result, status);
A = 10;
B = 11;
status = addGetStatus(A, B, &result);
__android_log_print(ANDROID_LOG_ERROR, "Add Status", "A: %d,
L6. LAB 6: REAL-TIME FIR FILTERING, QUANTIZATION EFFECT, AND OVERFLOW 105
B: %d, C: %d, Status: %#010x", A, B, result, status);
A = -10;
B = -10;
status = addGetStatus(A, B, &result);
__android_log_print(ANDROID_LOG_ERROR, "Add Status", "A: %d,
B: %d, C: %d, Status: %#010x", A, B, result, status);
A = 100;
B = -1000;
status = addGetStatus(A, B, &result);
__android_log_print(ANDROID_LOG_ERROR, "Add Status", "A: %d,
B: %d, C: %d, Status: %#010x", A, B, result, status);
A = -100;
B = -32768;
status = addGetStatus(A, B, &result);
__android_log_print(ANDROID_LOG_ERROR, "Add Status", "A: %d,
B: %d, C: %d, Status: %#010x", A, B, result, status);
A = 32767;
B = 1000;
status = addGetStatus(A, B, &result);
__android_log_print(ANDROID_LOG_ERROR, "Add Status", "A: %d,
B: %d, C: %d, Status: %#010x", A, B, result, status);
On an iOS platform, the same output is shown using the printf method:
unsigned int status;
short result;
short A = 32767;
short B = 32767;
status = addGetStatus(A, B, &result);
printf("A: %d,B: %d,C: %d,Status: %#010x ", A, B, result, status);
A = 32767;
B = -32768;
status = addGetStatus(A, B, &result);
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.171.202