#include rjmp Reset .def LFSR0 =r2 .def LFSR1 =r3 .def LFSR2 =r4 .def LFSR3 =r5 .def TAPS1 =r6 .def TAPS2 =r7 .def RND0 =r22 .def RND1 =r23 .def TMP1 =r24 .def U = r25 ;UPDATE_RAND - calculate a new bit in the pseudo-random number generator. ; ;Parameters: @0 = destination register (8-bit). ; The new bit will be shifted in from the right. ;Requires: TAPS1 = 0xd0, TAPS2 = 1 ;Modifies: SREG, LFSR0, LFSR1, LFSR2, LFSR3, @0 ;Cycles: 9 .macro UPDATE_RAND lsr LFSR3 ; Approximately equivalent C code: ror LFSR2 ; ror LFSR1 ; rnd = (rnd << 1) | (lfsr & 1); ror LFSR0 ; lfsr = (lfsr >> 1) brcc skip1 ; ^ (-(signed int)(lfsr & 1) & 0xd0000001u); eor LFSR3, TAPS1 skip1: brcc skip2 eor LFSR0, TAPS2 skip2: rol @0 .endmacro Reset: rjmp Main reti ;INT0 reti ;PCINT0 reti ;TIM0_OVF reti ;EE_RDY reti ;ANA_COMP reti ;TIM0_COMPA reti ;TIM0_COMPB reti ;WDT reti ;ADC Main: ; Initialize the MCU ; Setup clock prescaler (assumes 9.6 MHz internal RC osc @ >= 3V supply) ldi r16, 1 << CLKPCE ; Enable prescaler change out CLKPR, r16 ldi r16, 0 ; Set prescaler = 1 out CLKPR, r16 ; Setup stack. ldi r16, low(RAMEND) ; Set up the stack out SPL, r16 ldi r16, 0x1f ; Initialize PORTB0-4 = outputs out DDRB, r16 ; Initialize the PRNG clr LFSR3 clr LFSR2 clr LFSR1 ldi r16,1 mov LFSR0,r16 ldi r16, 0xd0 mov TAPS1, r16 ldi r16, 1 mov TAPS2, r16 clr RND0 clr RND1 clr U MainLoop: ; <-- 0 cycles out PORTB, U ; Update output ; Run PRNG UPDATE_RAND RND0 UPDATE_RAND RND0 UPDATE_RAND RND0 UPDATE_RAND RND0 UPDATE_RAND RND0 UPDATE_RAND RND0 UPDATE_RAND RND0 UPDATE_RAND RND0 UPDATE_RAND r16 bst r16, 0 ; Store bit in T flag ; <-- +83 cycles ; Select random bit in U to update cpi RND0, 1 ; subi RND0, 1 brlt Update_bit0 cpi RND0, 4 ; subi RND0, 3 brlt Update_bit1 cpi RND0, 16 ; subi RND0, 11 brlt Update_bit2 cpi RND0, 60 ; subi RND0, 39 brlt Update_bit3 cpi RND0, 234 ; subi RND0, 153 brlt Update_bit4 nop nop rjmp MainLoop ; <-- No bit updated: +14 cycles ; Update bit in U with a random bit. Update_bit0: bld U, 0 nop nop nop nop nop nop nop nop rjmp MainLoop ; <-- Bit 0 updated: +14 cycles Update_bit1: bld U, 1 nop nop nop nop nop nop rjmp MainLoop ; <-- Bit 1 updated: +14 cycles Update_bit2: bld U, 2 nop nop nop nop rjmp MainLoop ; <-- Bit 2 updated: +14 cycles Update_bit3: bld U, 3 nop nop rjmp MainLoop ; <-- Bit 3 updated: +14 cycles Update_bit4: bld U, 4 rjmp MainLoop ; <-- Bit 4 updated: +14 cycles ; <-- = 83 + 14 = 97 cycles /* D/A-converter network: R0 U0 o--XXXX--*---*---o Uout Option 1: Option 2: R1 | | E24 resistors E96 resistors U1 o--XXXX--* X < 0.1% error 1.2% error R2 | X Rs = 10k U2 o--XXXX--* X R0 = 39.0k + 2.7k 42.2k R3 | _|_ R1 = 51.0k + 2.4k 53.6k U3 o--XXXX--* GND R2 = 51.0k + 10.0k 60.4k R4 | R3 = 51.0k + 360 51.1k U4 o--XXXX-- R4 = 43.0k + 3.6k 46.4k */