This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Hello,
I'm trying to create a function to generate a random byte in my MSP430F2132. I've based my code on the application report slaa338: http://www.ti.com/lit/an/slaa338/slaa338.pdf, and from this FAQ: http://processors.wiki.ti.com/index.php/MSP430_FAQ#How_to_generate_random_number_with_MSP430_devices.3F
This is my code with some needed modifications (I want a byte, not a 16-bit integer):
// SMCLK from DCO, and ACLK from VLO
BCSCTL3 |= LFXT1S_2;
BCSCTL2 = 0x00;
BCSCTL1 = 0x00;
// CCI2B function in P1.7
P1SEL |= 0x80;
P1DIR |= 0x80;
P1SEL2 &= ~(0x80);
TACCTL2 |= CM_1 + CCIS_1 + CAP;
TACTL |= TASSEL_2 + MC_2;
for(i=0 ; i<8 ; i++)
{
// shift left result
result <<= 1;
// wait until Capture flag is set
while(!(TACCTL2 & CCIFG));
// clear flag
TACCTL2 &= ~CCIFG;
// check LSB
if(TACCR2 & 0x01)
{
result |= 0x01;
}
// Add 5 to BCSCTL1
BCSCTL1 = BCSCTL1 + 5;
// change the division of timer input clock
aux = (TACCR2 & 0x03) << 8;
TACTL = (TACTL & 0xFCFF) | aux;
}
This code works fine, although it seems not to give very "random" results, i.e. some particular results repeat themselves too often. To try to fix this, I've followed some tips from the aforementioned application report, for example adding 5 to the BCSCTL1 register every loop to change the DCO speed relative to the VLO. With this, in my opinion, the results are still not random enough.
Now, my problem comes when trying to apply another "adding randomness" tip, the one that proposes to have the result come from a majority vote of 5 loops. My first idea was to add a nested for loop that runs 5 times and counts the "1s" occurrences. However, whenever I use two nested loops the CCIFG flag doesn't seem to ever set. The following is one of my attempts:
P1SEL |= 0x80;
P1DIR |= 0x80;
P1SEL2 &= ~(0x80);
TACCTL2 |= CM_1 + CCIS_1 + CAP;
TACTL |= TASSEL_2 + MC_2;
for(i=0 ; i<8 ; i++)
{
numCeros = 0;
numUnos = 0;
// shift left result
result <<= 1;
for(j=0 ; j<5 ; j++)
{
// wait until Capture flag is set
while(!(TACCTL2 & CCIFG)); // Stuck here forever
// clear flag
TACCTL2 &= ~CCIFG;
// check LSB
if(TACCR2 & 0x01)
{
numUnos++;
} else {
numCeros++;
}
// Add 5 to BCSCTL1
BCSCTL1 = BCSCTL1 + 5;
// change the division of timer input clock
aux = (TACCR2 & 0x03) << 8;
TACTL = (TACTL & 0xFCFF) | aux;
}
if (numUnos > numCeros) {
result |= 0x01;
}
}
I've tried a lot of things, like clearing the timer registers, having the 8-times loop be inside the 5-times loop, and nothing seems to work. I've even tried to put two loops one after the other (instead of nested) and even that doesn't work:
TACCTL2 |= CM_1 + CCIS_1 + CAP;
TACTL |= TASSEL_2 + MC_2;
for(i=0 ; i<8 ; i++)
{
// shift left result
results[0] <<= 1;
// wait until Capture flag is set
while(!(TACCTL2 & CCIFG));
// clear flag
TACCTL2 &= ~CCIFG;
// check LSB
if(TACCR2 & 0x01)
{
results[0] |= 0x01;
}
// Add 5 to BCSCTL1
BCSCTL1 = BCSCTL1 + 5;
// change the division of timer input clock
aux = (TACCR2 & 0x03) << 8;
TACTL = (TACTL & 0xFCFF) | aux;
}
TACTL |= TACLR;
TACCTL2 &= ~CCIFG;
TACCTL2 |= CM_1 + CCIS_1 + CAP;
TACTL |= TASSEL_2 + MC_2;
for(i=0 ; i<8 ; i++)
{
// shift left result
results[1] <<= 1;
// wait until Capture flag is set
while(!(TACCTL2 & CCIFG)); // Stuck here forever ?!?!
// clear flag
TACCTL2 &= ~CCIFG;
// check LSB
if(TACCR2 & 0x01)
{
results[1] |= 0x01;
}
// Add 5 to BCSCTL1
BCSCTL1 = BCSCTL1 + 5;
// change the division of timer input clock
aux = (TACCR2 & 0x03) << 8;
TACTL = (TACTL & 0xFCFF) | aux;
}
I don't know what is failing and I don't know what else to try. Any help would be greatly appreciated, about my particular code, or even about another useful way to generate a random byte in a msp430. Thanks in advance.
Alba
Just my two cents: No matter how seemingly good is hardware RNG ( seems, particular one is not ;), you shall combine (XOR) it's output with Pseudo-RNG. Most P-RNG generators are based on LFSR. In case of RNG failure which can lead to 0-s or 1-s or some other steady pattern output, P-RNG still adds (pseudo)randomness in the output.
Ok, I'll take a look at that. Thank you for answering. Anyway, if someone has a hint on what may be the problem in my code, it'll be much appreciated. Thanks in advance!
I would try to do like this: run MCLK = SMCLK = DCO (or XTAL), ACLK=VLOCLK (or 32KHz quartz). Run Timer_A in free-running mode, run WDT in interrupt generation mode. Then at each WDT interrupt sample single least significant bit of timer. After 8 WDT interrupts we have hopefully random 8 bits.
I've tried this and it works fine. Thank you very much for the help. There are still some "repeated" results, but I think it may be random enough for my application. Just out of curiosity I'd like to know what could be the problem in my initial question (the nested loop approach not setting the flag), so if anybody has an idea it'll be appreciated. Thanks!
Well, real randomness includes any amount of repetitions. Give an ape a typewriter and sooner or later (rather later, I guess) you'll get Shakespeare's complete collection.Alba Rozas Cid said:There are still some "repeated" results,
If you follow Pi for enough digits, you'll find a place where there are lots of '7' in a row.
Oh, haha, I'm aware of that. I only said that because at first I got like 2 or 3 repeated results in a sample of around 10-12. I just thought the probability of that was small. Then I made some tweaks and now it seems to be working better.
By the way, given your experience with msp430, do you have any idea about what may be the problem in my original question? Thank you very much!
No direct explanation (et), but I found several oddities:Alba Rozas Cid said:do you have any idea about what may be the problem in my original question?
BCSCTL0=0;
This will set the DCO to 70..170kHz system clock. So ten MCLK cycles (and 10 timer clock ticks) are in the range of your ACLK signal. However, I'd expect that the CCIFG bit is almost always set then.
I had expected to have the timer ticking much faster than VLO, so it increases the randomness due to VLO variations. With timer clock in the range of 10* VLO clock (or even less), it will require 10% VLO variation (or more) to give 1 timer tick change in the result. Resulting in a large number of bits in a repeating pattern before the output flips to another pattern.
But maybe I didn't recognize some clever twist here. ;)
Also, i don't know what you're doing with P1.7. P1.7 is TA2 compare output signal. But you run TACCR2 in capture mode (so any output is static) and use an internal trigger anyway (ACLK from VLO). So these port pin manipulations are superfluous at best.
There's no BCSCTL0 in my code or in msp430f2132. I assume you mean BCSCTL1? I think I (wrongly) set it to 0 just to quickly clear the XTS bit in one attempt, and then forgot to remove the line or rewrite it properly. In any case, the problem is still there with or without modifying BCSCTL1.
You're maybe right about the timer not being fast enough relative to the VLO, I haven't really done the math. I'll try to speed up the timer clock and see if that increases the randomness. However, my actual problem is CCIFG not setting ONLY when I use two nested for-loops. When there's only one loop it works fine. This is what I don't understand.
Jens-Michael Gross said:Also, i don't know what you're doing with P1.7. P1.7 is TA2 compare output signal. But you run TACCR2 in capture mode (so any output is static) and use an internal trigger anyway (ACLK from VLO). So these port pin manipulations are superfluous at best.
If I understood it correctly, these port manipulations are done to make the ACLK the capture trigger signal through the CCI2B channel. I grasped that from table 14 in http://www.ti.com/lit/ds/symlink/msp430f2132.pdf. And to select the timer functionality I must set P1.7 according to table 21 in that same document. But you're right, nothing changes if I remove the port manipulations. So, did I understand it all wrong?
Thanks
Right. Typo.Alba Rozas Cid said:There's no BCSCTL0 in my code or in msp430f2132. I assume you mean BCSCTL1?
No, the ACLK connection for TA0.CCI2B is internal (as indicated in the table).Alba Rozas Cid said:If I understood it correctly, these port manipulations are done to make the ACLK the capture trigger signal through the CCI2B channel.
But I see where you confusion comes from. On older revisions of this datasheet, teh table didn't have a number (I was wondering where you got 'table14' from), but the entries int eh columns 'Module block' and 'module output signal' were four rows high while on the latest datasheet (with table nr.) they are int he first row followed by three separate, empty rowws. Which is totally obfuscating their meaning.
The "output pin number" columns are related to the 'module output signal' column and not to the 'module input name' column, but due to this quirk, it seems like P1.7 is related to CCI2B. Which it isn't. It is only related to TA2 output signal.
I've added this to my list of datasheet errors.
Hi JMG,
Jens-Michael Gross said:I've added this to my list of datasheet errors.
Hi Alba,
Alba Rozas Cid said:However, my actual problem is CCIFG not setting ONLY when I use two nested for-loops.
Looking into your code, this is indeed weird. The CCIFG should be set in either way (one loop or two loops): I will try to test your code today if i have time, anyway could you check whether the ACLK is always working? You can output ACLK to an output pin and see whether the clock signal runs. If the ACLK doesn't run, it will explain why the CCIFG is not set, but then you need to find out why it doesn't run.
Sure, it' snot confidential.Leo Hendrawan said:Is this list of datasheet errors of yours can be shared with others? :)
However, I have already forwarded an older version to Katie and some of my comments have been included in recent versions of datasheets. Figuring out what has been already 'fixed' is a time-consuming process. And for things that haven't been fixed in later datasheets, I don't know whether it is scheduled for future version or whether my comments were simply wrong and have been discarded.
I plan to feed the next bunch to Katie as soon as I'm through with removing 'fixed' issues from the list. (BTW: after deleting much that has been fixed, it's still 20k of text)
If you want, I can mail you the current state.
Hi Michael,
What should be configured to get ACLK as source for capture , the capture input select bits (CCISx) has only these options to select; 00 CCIxA, 01 CCIxB, 10 GND and 11 VCC.
So please let us know to configure ACLK as source for Capture input.
Bets Regards,
Santosh.
In the device datasheet the time rmodule description should contain a table telling you which CCIxA/B signal is connected where. On some CCRx units, CCIxB is internally connected to ACLK, on others, both CCIs are connected to two port pins. It is different for each MSP.
THis is why sample codes often only work on the exact MSP they were written for. Because on other MSPs even of the same family, the internal connecitons may be different, or the output of one module that is implicitely used as input for another, is on two separate pins on the other MSP.
Hi Michael,
Thanks for the reply, I referred the datasheet and configured the proper CCIS and also interrupt flag is setting but always the result is same no change in the
values, no randomness, please let us know how can be done.
Best Regards,
Santosh.
**Attention** This is a public forum