%CMPE 415 HW8 MATLAB CODE to Check Hardware
%Summary:
%Reads image from disk into im8
%Computes 2D fft in matlab and plots result using floats
%Computes 2D fft on FPGA by 1)sending square image as a) first byte is log-base-2 of length of side 
%                                                     b) then, image is send row-wise, first row sent left to right followed by second row (each pixel is uint8, 1 megabyte total for 1024x1024 size image)
%                           2)Recieving two signed int16 arrays (total of 4 megabytes for 1024x1024 size image)
                               %recieved column-wise, first column top to bottom recieved first, then second colmn
                               %real and imaginary 16-bits words alternate with real comming first
%Finally, the results from the FPGA are plotted


numRows=1024;  %change these numbers to resize image and affect send/recieve size appropriately
numCols=1024;
log2size=uint8(log(1024)/log(2));

%declare data for FPGA FFT2 result
fftRealFPGA=zeros(numRows,numCols);
fftImagFPGA=zeros(numRows,numCols);
%declare data for Matlab FFT2 result
fftRealMatlab=zeros(numRows,numCols);
fftImagMatlab=zeros(numRows,numCols);

%% read image into im8
im8=imread('dogparadetrio_1024_1024_Gray.png'); %8 bit result
[imRows,imCols,imColors]=size(im8);
if (imColors)>1  %if not grayscale, take green channel
    im8=squeeze(im8(:,:,2)); %remove any "extra" dimentions
end
im8 = imresize(im8, [numRows numCols]); %resize to proper size if needed
%im = 1.0*im8; %floating point version


%% Compute fft2 in Matlab
Y=fft2(im8);
fftRealMatlab=real(Y);
fftImagMatlab=imag(Y);

%% Plot Result
figure(1001);
subplot(2,2,1);
imshow(fftRealMatlab,[]);colormap gray;colorbar;title('Matlab Real Result'); 
subplot(2,2,2);
imshow(fftImagMatlab,[]);colormap gray;colorbar;title('Matlab Imaginary'); 

%% Use FPGA to compute result (send size and uint8 data and receive total of two signed
%%%                             16-bit arrays)
%%%
%% Open Serial Port
serialObj = serial('COM1','BaudRate',115200,'Terminator','');
fopen(serialObj);


%% Send size
fwrite(serialObj,log2size,'uint8')

%% Send image
%make 2D image data into one vector, scanning left to right and working downward
temp=im8';
dataVectorOut=temp(:)'; 
%send data
fwrite(serialObj,dataVectorOut,'uint8')

%% Read Image
%wait for data to start comming
while(serialObj.BytesAvailable==0)
end

%read data 
%sent column-wise, first column top to bottom sent first, then second colmn
%real and imaginary 16-bits words alternate with real comming first
for col=0:(numRows-1) %iterate over columns
    for row=0:(numRows-1) %iterate over rows
        for flag_imag_real=0:1 %iterate over real then imag
            highByte=fread(serialObj,numCols,'uint8');
            lowByte=fread(serialObj,numCols,'uint8');
            word16=highByte*256+lowByte;
            if(word16>(2^(16-1)-1)) %number is negative
                signedInteger=-1*(((2^16-1)-word16)+1);
            else                %number is positive
                signedInteger=word16;
            end
                
            if flag_imag_real==0 %if real result
                fftRealFPGA(row+1,col+1)=signedInteger;
            else                 %if real result
                fftImagFPGA(row+1,col+1)=signedInteger;
            end
        end
    end
end
%% Close serial port and dispose of com object
fclose(serialObj);
delete(serialObj);
clear serialObj


%% Plot the FPGA result
figure(1001);
subplot(2,2,3);
imshow(fftRealFPGA,[]);colorbar;title('FPGA Real Result'); 
subplot(2,2,4);
imshow(fftImagFPGA,[]);colorbar;title('FPGA Imaginary'); 


