0

I am using MSP430FR5969 microcontroller with code composer studio IDE to make a pseudo-random number generator. I referred to this wikipedia page for that. It works fine with 8-bit but in case of 16-bit, the control doesn't go the lines after the do-while loop but instead go back to initialization block (for example: if I place a breakpoint at line uint16_t period = 0, it hits it).

Can someone explain this behavior?

Here is my code:

#include <stdint.h>
#include <msp430fr5969.h>
int main(void)
{
uint16_t lfsr = 0xACE1;  //any non-zero value is fine
uint16_t period = 0;
do
{
    unsigned lsb = lfsr & 1;
    lfsr >>= 1;                /* Shift register */
    if (lsb)
            lfsr ^= 0xB400;    /* taps: 16 14 13 11; characteristic polynomial: x^16 + x^14 + x^13 +   x^11 + 1 */
    ++period;
} while(lfsr != 0xACE1);  //loop until random number becomes equal to starting value

return 0;
}

Thank you!

ggn993
  • 27
  • 7

3 Answers3

0

Not sure where exactly problem is, but I usually force code to avoid implicit promotions, mix of int and unsigned in one op, mix of operands of different sizes etc

Code below works for me under 3 compilers, though I cannot try it on MSP430 dev.tools. Output period is 65535

Care to try?

#include <stdint.h>
#include <stdio.h>

int main() {
    const uint16_t USONE = 1U;
    const uint16_t B400  = 0xB400U;
    const uint16_t SEED  = 0xACE1U;

    uint16_t lfsr   = SEED;  //any non-zero value is fine
    uint32_t period = 0U;
    do
    {
        uint16_t lsb = lfsr & USONE;
        lfsr >>= USONE;   /* Shift register */
        if (lsb)
            lfsr ^= B400;    /* taps: 16 14 13 11; characteristic polynomial: x^16 + x^14 + x^13 +   x^11 + 1 */
        ++period;
        printf("LFSR: %d %x\n", period, lfsr);
    } while (lfsr != SEED);  //loop until random number becomes equal to starting value

    printf("Period: %d\n", period);

    return 0;
}

Output, first 10 values

LFSR: 57968
LFSR: 28984
LFSR: 14492
LFSR: 7246
LFSR: 3623
LFSR: 45843
LFSR: 60809
LFSR: 49860
LFSR: 24930
LFSR: 12465

last 10 or so values

LFSR: 65524 c4e5
LFSR: 65525 d672
LFSR: 65526 6b39
LFSR: 65527 819c
LFSR: 65528 40ce
LFSR: 65529 2067
LFSR: 65530 a433
LFSR: 65531 e619
LFSR: 65532 c70c
LFSR: 65533 6386
LFSR: 65534 31c3
LFSR: 65535 ace1
Period: 65535
Severin Pappadeux
  • 18,636
  • 3
  • 38
  • 64
  • MSP430 is a 16-bit CPU, and the original code is compiled correctly. – CL. Oct 21 '18 at 08:08
  • @CL. There is a difference between "compiled correctly" and "works like intended", like there is a difference between theory and practice. `MSP430 is a 16-bit CPU` I know that, but life taught me when dealing with bitwise operations, always use unsigned (no implicit promotions), and always use desired word width (no widening promotions), thus avoiding bad code generation and surprises later. Anyway, MSP430 should support 32bit ints, I believe, so for the case where overflow is possible, use it – Severin Pappadeux Oct 21 '18 at 15:21
  • I actually checked the MSP430 assembler output. My point was that your rewrite, while an improvement, had no effect on the actual question. – CL. Oct 21 '18 at 15:30
  • Thanks for your code but my code runs like it did before and the value for period goes upto 452460544 if I place a breakpoint at (lfsr = SEED). I also tried @CL's suggestions and added some code after while loop but control never goes there and it doesn't get executed. – ggn993 Oct 22 '18 at 01:17
  • @ggn993 Interesting. Ok, I printed first 10 (actually, all 65535 of them) LFSR values, check the update. Could you please rerun code with LFSR output and compare? – Severin Pappadeux Oct 22 '18 at 01:36
  • Yes these values are the same – ggn993 Oct 22 '18 at 02:35
  • @ggn993, ok, updated code to print period and lfsr together, put out last 10 values. – Severin Pappadeux Oct 22 '18 at 03:32
  • @ggn993 I've put on my google drive whole output, zip file, https://drive.google.com/open?id=1bRl85JiRcqBpzvxQ2ciSip_zsWYbM-VO – Severin Pappadeux Oct 22 '18 at 03:40
  • I used IAR Embedded Workbench this time and the same code works fine...don't know what's wrong with CCS. Thanks for your help! – ggn993 Oct 22 '18 at 13:31
  • @ggn993 Glad to hear. So, compiler error at the end. – Severin Pappadeux Oct 22 '18 at 15:02
0

The period variable is never read, so it is likely to be optimized away. Furthermore, a microcontroller does not have an OS to return to, so returning from main() is pointless.

You have to put some actual code after the loop, and it should do something with period. The default destination of printf is the CCS debug console, so you could call that, but if you just want to observe the variable in the debugger, write the final value to some hardware register or to some volatile variable so that the compiler is forced to keep its value:

MPY = period;
CL.
  • 173,858
  • 17
  • 217
  • 259
  • Thanks for your reply but problem still persists. I declared volatile uint32_t MPY variable, initialized it to zero and later assigned it the value of period after the while loop. If I place a breakpoint there, control never reaches that location but if I place it in initialization part, value of MPY becomes 17956864 while the value of period becomes 452460544. – ggn993 Oct 22 '18 at 01:25
0

Quick hint if you trying it on real hardware, have you disabled the hardware watchdog that automatically starts at powerup?

Damiano
  • 698
  • 7
  • 19