Hi to you all,I'm working on a project involving the LPC Link2 to evaluate its LPC4370 (the one on the board is actually the LPC4370JFET100) for real-time data processing: a more datailed description of my work was given in this question.What I need to do is:
Basically I just need to sum the samples acquired. The ADC packs two 12-bit wide samples in offset binary (due to the fact that the firmware uses thresholds) into one 32bit word. Thanks to Thibaut ZEISSLOFF's code I was able to extract maximum and minimum very fast: now I'm trying to adapt another of his algorithms (kindly published on his interesting blog m4-unleashed.com).
Here's my code:
__RAMFUNC(RAM) void sum_SMLAD(int32_t* pSrc, uint32_t pSize) { int32_t sum = 0; uint32_t pair, loop = pSize >> 2; while ((loop-- > 0) && wordsLeft) { pair = *__SIMD32(pSrc)++; sum = __SMLAD(pair, 0b10000000000000011000000000000001u, sum); pair = *__SIMD32(pSrc)++; sum = __SMLAD(pair, 0b10000000000000011000000000000001u, sum); wordsLeft -= 2; } if (pSize & 0x2) { pair = *__SIMD32(pSrc)++; sum = __SMLAD(pair, 0b10000000000000011000000000000001u, sum); wordsLeft -= 1; } if(wordsLeft == 0) { peaksCounter -= 1; accumulator[peaksCounter] = sum; } return; }
Unfortunately I always run into a Hardfault around the first couple of iteration of the main while loop.Here's how SMLAD is defined in core_cm4_simd.h:__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); }Since the SMLAD intrinsic basically takes 2 words then does (first_top_halfword*second_top_halfword)+(first_bottom_halfword*second_bottom_halfword) im' trying to multiply by one and possibly facing two issues:
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) { uint32_t result; __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); return(result); }
Thanks for your patience: any help would be highly appreciated! Regards,Andrea
Hi Andrea,
If I understand correctly, you get samples in range [0; 4095] that represent signed value between -2048 and 2047.
If that is the case, you see your problem the following way, writing r[i] raw samples (with offset) and s[i] corresponding signed sample, therefore s[i] = r[i] - 2048.
You can perform the sum operation on raw samples directly and then remove the offset :
raw_sum = r[0] + r[1] + ... + r[N-1] = s[0] + ... + s[N-1] + N*2048
signed_sum = raw_sum - N*2048
Regarding SMLAD usage, I'm not quite sure why you are using 0x80018001 constant, that means that you multiply each raw sample by -32767 (0x8001).
In order to multiply by 1 each raw sample, your constant would need to be 0x00010001 or 0b00000000000000010000000000000001.
Let me know if I did not undertand properly your need !
Thanks for the mention by the way !
Regards,
Thibaut
Thanks Thibaut ZEISSLOFF, I got what you mean.I was trying to mulply for those number just beacause I just shutted down my brain and looked at a wikipedia table:
Anyway, do you suggest to use the SMLAD? I should remove the offset anyway before using SMLAD right?You're welcome, I had to mention you and your blog. Your work is helping me a lot.