// LFSR 31 bits - stages 3,31 // Jed Margolin 10/27/2018. // Built with Code Composer Studio v7 // MSP430G2402 but could use almost anything. The code is only 566 bytes. // Inline code, no interrupts // Use DCO (16MHz) for TIMERA, SIMCLK, and MCLK // stages 3 and 31 are d30 and d2 // 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 // 1 1 // Sequence is 2,147,483,647 long // For 10ms delay, clock 1250 times // Port 1: d0 = ACLK, d1 = lfsr1, d2 = lfsr2, d3 = timing clock //================================================ #include #define DELTA_1MHZ 244 // 244 x 4096Hz = 999.4Hz #define DELTA_8MHZ 1953 // 1953 x 4096Hz = 7.99MHz #define DELTA_12MHZ 2930 // 2930 x 4096Hz = 12.00MHz #define DELTA_16MHZ 3906 // 3906 x 4096Hz = 15.99MHz #define TIME 100 #define DCOUNT 8 #define FREQ 40 void wait(unsigned int); void wait2(void); void Set_DCO(unsigned int Delta); volatile unsigned int timer_flag = 0; int main(void) { unsigned char caldata1, caldata2; // Temp. storage for constants unsigned int n,temp1,temp2; unsigned int lfsr1L,lfsr1H,lfsr2L,lfsr2H; // unsigned int lfsr1,lfsr2; WDTCTL = WDTPW + WDTHOLD; // Stop WDT wait(500); // give the crystal 500ms to stabilize P1SEL &= ~(BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0); // Out P1SEL2 &= ~(BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0); // not in 2121 P1DIR |= (BIT7|BIT6|BIT5|BIT4|BIT3|BIT2|BIT1|BIT0); // P2SEL &= ~(BIT5|BIT4|BIT3|BIT2|BIT1|BIT0); // Out P2SEL2 &= ~(BIT5|BIT4|BIT3|BIT2|BIT1|BIT0); // not in 2121 P2DIR |= (BIT5|BIT4|BIT3|BIT2|BIT1|BIT0); // // P1.0 for ACLK P1SEL |= BIT0; // ACLK P1SEL2 &= ~(BIT0); P1DIR |= BIT0; // Lock the DCO to the 32.768 KHz crystal - 16 MHz Set_DCO(DELTA_16MHZ); // Set DCO and obtain constants caldata1 = DCOCTL; // for debugging caldata2 = BCSCTL1; // CCTL0 = CCIE; // CCR0 interrupt enabled // CCR0 = FREQ-1; // 16 MHz / 40 = 400 Hz // TACTL |= TACLR; // clear timer // TACTL = TASSEL_2 + MC_1; // SMCLK, upmode, clear timer // __bis_SR_register(GIE); // Enable interrupts // 31 bits lfsr1L = 0x4000; lfsr1H = 0x4000; lfsr2L = 0x4000; lfsr2H = 0x4000; // Delay lfsr2 for 10ms by clocking 1250 times first for(n=625; n>0; n--) { temp1 = lfsr2L>>2; temp2 = lfsr2H>>14; // both are now at d0 temp1 = (temp1 ^ temp2) & 0x0001; if(lfsr2L & 0x8000) { lfsr2H = lfsr2H<<1 | 0x0001; // shift a '1' into lfsr2h } else { lfsr2H = lfsr2H<<1; // shift a '0' into lfsr2h } lfsr2L = (lfsr2L<<1) | temp1; // shift lfsr2l and make d0 0' or '1' depending on d31 ^ d2 } while (1) // main loop { P1OUT |= BIT3; //lfsr1 temp1 = lfsr1L>>2; temp2 = lfsr1H>>14; // both are now at d0 temp1 = (temp1 ^ temp2) & 0x0001; if(lfsr1L & 0x8000) { lfsr1H = lfsr1H<<1 | 0x0001; // shift a '1' into lfsr1h } else { lfsr1H = lfsr1H<<1; // shift a '0' into lfsr1h } lfsr1L = (lfsr1L<<1) | temp1; // shift lfsr1l and make d0 '0' or '1' depending on d31 ^ d2 // output it if(lfsr1L & 0x01) { P1OUT |= BIT1; } else { P1OUT &= ~BIT1; } // lfsr2 temp1 = lfsr2L>>2; temp2 = lfsr2H>>14; // both are now at d0 temp1 = (temp1 ^ temp2) & 0x0001; if(lfsr2L & 0x8000) { lfsr2H = lfsr2H<<1 | 0x0001; // shift a '1' into lfsr2h } else { lfsr2H = lfsr2H<<1; // shift a '0' into lfsr2h } lfsr2L = (lfsr2L<<1) | temp1; // shift lfsr2l and make d0 '0' or '1' depending on d31 ^ d2 // output it if(lfsr2L & 0x01) { P1OUT |= BIT2; } else { P1OUT &= ~BIT2; } P1OUT &= ~BIT3; // end of timing mark } // end while main loop } // end main //==================================================== //==================================================== // Timer A0 interrupt service routine // CCS 7 requires this extra crap #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A (void) #elif defined(__GNUC__) void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer_A (void) #else #error Compiler not supported! #endif { P1OUT ^= BIT1; // Toggle P1.1 } //========================================================== void wait(unsigned int time) { volatile unsigned int i,j; for(i=time; i>0; i--) { for(j=382; j>0; j--); { } } return; } //========================================================== void wait2() { volatile unsigned int i; for(i=0; i<48; i++){} return; } //======================================================== void Set_DCO(unsigned int Delta) // Set DCO to selected frequency { unsigned int Compare, Oldcapture = 0; // XT2OFF; LF Mode; DIVA_3: ACLK = LFXT1CLK/1 BCSCTL1 |= DIVA_3; // MCLK is DCOCLK; Divider /1; SIMCLK is DCOCLK; SMCLK Divider /1; DCOR // BCSCTL2 = 0; Reset = 0 anyway // Oscillator capacitor 12.5pF BCSCTL3 |= XCAP_3; // not used with MSP-EXP430G2ET // Timer/Capture TACCTL0 = CM_1 + CCIS_1 + CAP; // Timer A Control TACTL = TASSEL_2 + MC_2 + TACLR; // SMCLK, cont-mode, clear while (1) { while (!(CCIFG & TACCTL0)); // Wait until capture occured TACCTL0 &= ~CCIFG; // Capture occured, clear flag Compare = TACCR0; // Get current captured SMCLK Compare = Compare - Oldcapture; // SMCLK difference Oldcapture = TACCR0; // Save current captured SMCLK if (Delta == Compare) break; // If equal, leave "while(1)" else if (Delta < Compare) { DCOCTL--; // DCO is too fast, slow it down if (DCOCTL == 0xFF) // Did DCO roll under? if (BCSCTL1 & 0x0f) BCSCTL1--; // Select lower RSEL } else { DCOCTL++; // DCO is too slow, speed it up if (DCOCTL == 0x00) // Did DCO roll over? if ((BCSCTL1 & 0x0f) != 0x0f) BCSCTL1++; // Sel higher RSEL } } TACCTL0 = 0; // Stop TACCR0 TACTL = 0; // Stop Timer_A BCSCTL1 &= ~DIVA_3; // ACLK is divide by 1 } //================================================================= /* // 15 bit lfsr lfsr1 = 0x4000; lfsr2 = 0x4000; // Delay lfsr2 for 10ms by clocking 1724 times first for(n=1428; n>0; n--) { temp1 = lfsr2; temp2 = lfsr2>>14; // both are now at d0 temp1 = (temp1 ^ temp2) & 0x0001; lfsr2 = lfsr2<<1; // shift lfsr2l lfsr2 |= temp1; // '0' or '1' depending on d14 ^ d0 } //----------- while (1) // main loop { P1OUT |= BIT2; //lfsr1 temp1 = lfsr1; temp2 = lfsr1>>14; // both are now at d0 temp1 = (temp1 ^ temp2) & 0x0001; lfsr1 = lfsr1<<1; // shift lfsr1l lfsr1 |= temp1; // '0' or '1' depending on d14 ^ d0 // output it if(lfsr1 & 0x01) { P1OUT |= BIT0; } else { P1OUT &= ~BIT0; } // lfsr2 temp1 = lfsr2; temp2 = lfsr2>>14; // both are now at d0 temp1 = (temp1 ^ temp2) & 0x0001; lfsr2 = lfsr2<<1; // shift lfsr2l lfsr2 |= temp1; // '0' or '1' depending on d31 ^ d2 // output it if(lfsr2 & 0x01) { P1OUT |= BIT1; } else { P1OUT &= ~BIT1; } P1OUT &= ~BIT2; // end of timing mark } // end while main loop } // end main */ //=======================