#include #include #include #include #pragma regalloc- /* Definitions of all PORT pins * PA0 - PA7 = memory addressing - column * PB0 = odb_clk active low * PB1 = sdata * PB2 = iag1,2_clk, sag_clk active low * PB3 = srg_clk active low, cdsclk2 active low enable * PB4 = rst_clk, active high * PC0 - PC7 = memory addressing - row * PD0 = usart_rec * PD1 = usart_tr * PD2 = mem_ce active low * PD3 = mem_oe active low | CCD_ADB control | mem buffer chip enable * PD5 = sload * PD6 = ad_oeb active low * PD7 = row memory addressing msb */ void data(void); //store address calculations in RAM for quick access register char col @13; register char row @14; #pragma regalloc+ //force variables in RAM unsigned char srg,ptm,odb,integ,sload,readout,rec_en; //flags unsigned char count0,count1,q; //counters unsigned char ccdstate; //state unsigned char temp; unsigned char r_char; //received char unsigned char msb; //msb of row mem address int w; //row counter interrupt [TIM0_COMP] void sgen(void) { //turn on odb if(!odb) { PORTB.0 = 0; //odb_clk is high, making ODB high if(count0 > 10 ) { odb = 1; printf("odb\r\n"); PORTB.0 = 1; //turn off odb, switch to integration time count0 = 0; ccdstate = 1; OCR0 = 250; TCNT0 = 0; //reset current state of timer0 counter, for integration time } else { count0++; odb = 0; } } if(!integ) { //integration time of 15us has been achieved cuz of ocr0 = 250 integ = 1; //integration time is over printf("integr\r\n"); ccdstate = 2; //switch to parallel transfer mode for ccd; } //parallel transfer if(!ptm) { if(count1<11) { count1++; //increment by integers to represent 10us.. //turn on transfer to memory crystal oscillators -- iag1-2, sag, srg PORTB.2 = 0; //iag1-2, sag clk is on, srg is on cuz of iag1-2 being on active low - nand gate PORTB.3 = 0; //srg clk is on active low ccdstate = 2; } else { //500 pulses done ptm = 1; PORTB.2 = 1; //iag1-2, sag clk off active low PORTB.3 = 1; //srg clk off active low printf("ptmdone\r\n"); ccdstate = 3; //get out of parallel transfer go to sload count1 = 100; //never get into parallel tranfer again } } //set up AD9822 mux register and config regs if(!sload) { //set up AD9822 -- sclk is connected to adcclk, turn on adcclk, the defaults for mux reg is ok, change config. reg of AD9822 PORTD.5 = 0; //turn on sload, active low //send in configuration as sdata... 0000xxx001011000.. 1channel mode cds, each instruction takes 62.5ns, I want each bit to be on for 200ns PORTB.1 = 0; //62.5ns #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 1; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 1; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 1; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTB.1 = 0; #asm nop //62.5ns nop //125ns nop //187.5ns #endasm PORTD.5 = 1; //turn off sload sload = 1; //no change AD9822 config reg needed anymore ccdstate = 4; //change state to readout transfer printf("sload on\r\n"); OCR0 = 250; } //serial readout if(!readout && srg) { //srg-clk and rst-clk are running creating pulses, and AD9822 os digitizing it PORTD.6 = 0; //turn on AD9822 output printf("serialreadoutYEA\r\n"); //store to memory, generate address for(w=0; w<444; w++) { for(q = 0; q<255; q++) { PORTA = q; //col } if(w>255) { //msb = 1; PORTD.7 = 1; //row msb } else { //msb = 0; PORTD.7 = 0; //row msb } PORTC = (char)w; //row } readout = 1; //serial readout done srg = 0; ccdstate = 5; //serial readout is done } } //send data to matlab void data(void) { DDRB = 0x00; //make PORTB an input PORTB = 0xff ; while(1) { //did i receive a char? if (UCSRA.7) { r_char = UDR; //get char from UDR if (r_char=='g') { if(!rec_en) { //generate addresses if(col==255) { col = 50; if(row==255) { //msb=1; row = 125; PORTD.7 = msb; } else { row++; } } else { col++; } PORTA = col; //output column address PORTC = row; //output row address temp = PINB; //read the memory data printf("%d\r",temp); //send to matlab terminator character is a carriage return } else { PORTD.7 = 0; //msb = 0; } //store image from matlab 100 x 128 - matlab giving data back to uC for maybe blasting on TV if(r_char == 'b') { rec_en = 1; } if(rec_en) { //good place to blast data from MATLAB onto the TV, not implemented } } } } } void main(void) { /* * PORTA = write to memory *PORTB = CLK for CCD, AFE, read from memory *PORTC = memory addressing *PORTD = USART, TV_Sync, MeM controls, AFE Output Enable, LED */ //ALL THE CODE IS DONE FOR 5MHz //set all ports as output DDRA = 0xff; DDRB = 0xff; DDRC = 0xff; DDRD = 0xff; //set up timer 0 //turn on timer 0 compare match ISR TIMSK=2; TCNT0= 0; //set the compare reg to 0 time ticks, stay in interrupt //1cycle = 16us (with timer0 overflow upto 255), then 16us/255 = 62.7ns per count of the timer, and 10^3ns = 1us, then 10^3ns/62.7ns = 16counts per us OCR0 = 250; //prescalar to 1 and turn on clear-on-match - CTC on TCCR0=0b00001001; //enable hyptrm for debug purposes UCSRB = 0x18 ; //enable reciever, transmitter.. 0x98 to enable rec/xmit isr UBRRL = 103; //76.8k baud //turn on CCD and AFE, turn off MeM PORTB.0 = 1; //odb in transfer mode, not clear mode PORTD.2 = 1; //turn off mem PORTD.3 = 1; //turn on CCD, turn off buffer chip, mem output off PORTD.6 = 1; //turn off AFE output PORTD.7 = 0; //turn on led, msb = 0 PORTB.2 = 1; //turn off iag sag .. active low PORTB.3 = 1; //turn off srg .. active low PORTB.4 = 0; //turn off rst.. active high sload = 1; //turn off serial AD9822 setup enable //initialize variables and flags count0 = 0; odb = 1; readout = 1; ptm = 1; integ = 1; ccdstate = 0; col = 0; row = 0; printf("start\r\n"); //turn on interrupts #asm sei #endasm while(1) { switch(ccdstate) { //ODB high for 1us -- make everything 16counts per us case 0: //odb odb = 0; OCR0 = 32; break; //integration time case 1: integ = 0; OCR0 = 250; //1 count = 62.5ns, 250 counts = 15.6us TCNT0 = 0; break; //transfer to memory of ccd case 2: //turn on crystal oscillator circuits for 500 pulses, 5MHz gives period of 200ns, 200ns*500 = 100us if(ptm) { ptm = 0; OCR0 = 160; //count by 10us for parallel transfer state } break; //set up config regs for AD9822 case 3: if(sload) { PORTD.4 = 1; sload = 0; } break; //Readout to serial.. 684 pulses of SRG, RST + 1 SRG pulse to indicate single register readout // 80ns*684 = 54.7us.. 54.7us/11 = 4.97 = 5, count by 11us, set OCR0 = 175 case 4: //check for timing between cdsclk1,2 and serial readout of the signal, according to waveform -- they are in sync -- but should it be??? //set up memory addressing if(readout) { PORTD.2 = 0; //turn on mem -- 62.5ns PORTD.3 = 1; //mem output is off -- makes ad9822 and ccd on PORTD.6 = 0; //turn on AFE output PORTB.2 = 1; //turn off SAG, IAG1,2 clk PORTB.3 = 0; //turn on srg-clk for one pulse -- single reg readout for ccd, active low, cdsclk2 on PORTB.4 = 1; //turn on rst-clk.. look in interface design for waveform, delayed from srg by 62.5ns //play around with PORTB.3 PORTB.4 to get the right pulse for serial readout /*PORTB.3 = 0; //need 100ns pulse, but 62.5*2 = 125ns.. close enough PORTB.3 = 1; //turn off srg-clk... one pulse is done.. PORTB.3 = 0; //turn on srg-clk late for the needed waveform, also it is active low */ //PORTB.4 = 1; //turn on rst-clk.. to be synced up with srg-clk, active high, turn on cds1 as well //PORTB.5 = 1; //turn on adcclk, cdsclk1, cdsclk2 -- 62.5ns printf("srgon\r\n"); srg = 1; readout = 0; //need to start serial readout transfer OCR0 = 175; //count by 11us for readout state TCNT0 = 174; //go to serial readout immediately } break; //put stuff from else statement here.. 684pulses done? case 5: //684 pulses done printf("\rserialdone\r\n"); PORTD.7 = 1; PORTD.6 = 1; //turn off afe output PORTB.4 = 0; //turn off rst-clk, active high.. PORTB.3 = 1; //turn off srg-clk active low, cdsclk2 off PORTD.7 = 0; //msb of mem row addr is zero -- 62.5ns OCR0 = 250; // ccdstate = 6; //set up UART break; //UART set up and blast TV, set timer here case 6: printf("uart\r\n"); UCSRB = 0x18 ; //enable reciever, transmitter.. 0x98 to enable rec/xmit isr UBRRL = 103; //9600 baud PORTD.3 = 0; //turn off ccd, turn on buffer chip, and mem output //memory readout address generation row = 0; col = 0; msb = 0; PORTD.7 = 0; //make msb of row addr = 0 ccdstate = 6; data(); //generate addresses and send memory output to matlab break; } } }