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
Is there a way to provide a good old printf log before each smlad call, in order to check :
I see that you're using SIMD32 instructions. Are data well-aligned ? SIMD32 is more likely to cause various problems with unaligned data accesses.
One way to check if it's not the SIMD32 instructions causing the error would be to replace them with simple instructions.
I Myy (myy), thanks for your reply. Excuse me for being this late in the answer but I checked the whole firmware in these day and found a huge bug. I explained it in this other queston.
Anyway, regarding the problem here discussed, I managed to have no errors: I forgot the
wordsLeft -= 2;
line and once I added it, it "worked" (means no hardfaults).
Yes, the buffers are all well aligned, except the accumulator array. That is declared as follows:
__DATA(RAM4) static uint32_t accumulator[PEAKS_NUM];
To get reasonable results I think I need to modify the call to SMLAD because of the 12 bit offset binary used by the adchs.Now I'll try to figure out how to manage those samples in SMLAD, if you have any suggestion feel free to contribute! Thanks again for your reply by the way.
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.