`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    14:14:10 12/29/2014 
// Design Name: 
// Module Name:    Bluetooth 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module Bluetooth
(
	input clk,
	input reset,
	input rxd,
	output txd
 );
														
parameter CLOCKS_PER_BIT = 1302;     // baud rate : 38400bps, Clock : 50MHz, 20ns
parameter CLOCKS_WAIT_FOR_RECEIVE = 651;
parameter MAX_TX_BIT_COUNT =9;
parameter MAX_DATA_BUFFER_INDEX =15;

reg [15:0] tx_clk_count=0;        // clock count
reg [3:0]  tx_bit_count=0;        // bit count [start bit | d0 | d1 | d2 | d3 | d4 | d5 | d6 | d7 | stop bit]
reg [7:0]  data_buffer_index=0;
reg [3:0]  data_buffer_base=0;

reg [7:0] data_buffer [0:24];        // tx data buffer
reg [7:0] data_setup [0:80];        // bluetooth setup tx data buffer
reg [7:0] data_buffer_rx [0:4];        // rx data buffer
reg [7:0] data_tx=0;          // data to transmit

reg [7:0] rx_data=0;
reg [3:0] rx_bit_count=0;
reg [11:0] rx_clk_coun=0;
reg [32:0]sec_cnt =0;
reg state_rx=0;
reg tx_bit=0;
reg [1:0] toggle=0;
reg [31:0]timer_cnt = 0;
reg [11:0] rx_clk_count = 0;

// Transmitter Process
// at every rising edge of the clock
reg [31:0]timer_cnt_setup = 0;

reg sel_mux = 0;
always @ (posedge clk)
begin
  if(reset == 1)begin
		tx_clk_count = 0;
		tx_bit_count = 0;
		tx_bit = 0;                     // set idle
		data_buffer_index = 8'd0;          // data index
  end
  else 
	begin
// transmit data until the index became the same with the base index
//  if ( data_buffer_index != data_buffer_base ) begin
			if(timer_cnt == timer_cnt_setup)
			begin
				if (tx_clk_count == CLOCKS_PER_BIT) 
					begin
						if (tx_bit_count == 0)
							begin
							tx_bit = 1;     // idle bit
							tx_bit_count = 1;
							case(sel_mux)
							0: data_tx = data_setup[data_buffer_index];			 
							1: data_tx = data_buffer[data_buffer_index];		
							endcase
						  
							end
					  else if (tx_bit_count == 1) 
								  begin
										tx_bit = 0;     // start bit
										tx_bit_count = 2;
								  end
					  else if (tx_bit_count <= MAX_TX_BIT_COUNT) 
								  begin
										tx_bit = data_tx[tx_bit_count-2];   // data bits
									//	tx_bit = 1;   // data bits
										tx_bit_count = tx_bit_count + 1;
								  end
					  else 
							  begin
									tx_bit = 1;     // stop bit
									data_buffer_index = data_buffer_index + 1;  // if the index exceeds its maximum, it becomes 0.
									timer_cnt = 32'd0;
									tx_bit_count = 0;
									if(data_buffer_index == 8'd25 && sel_mux) //bluetooth trans data
									begin
										data_buffer_index = 8'd0;
									end 
									else if(data_buffer_index == 8'd81) //bluetooth trans data for setup
									begin
										sel_mux = 1'b1;
										data_buffer_index = 8'd0;
									end 
							  end
							  tx_clk_count = 0;   // reset clock count
				 end
				tx_clk_count = tx_clk_count + 1;        // increase clock count
		end
		else timer_cnt =  timer_cnt + 1'b1;
	end
end

wire or_flag = (data_buffer_index == 8'd3)|(data_buffer_index == 8'd12)|(data_buffer_index == 8'd25)|
					(data_buffer_index == 8'd37)|(data_buffer_index == 8'd51)|(data_buffer_index == 8'd62);
always@(posedge clk)
begin
	    if (reset == 1) 
		 begin
				timer_cnt_setup <= 32'd0;
       end
		 else
			begin
			if(or_flag == 1'b1)
				begin
					timer_cnt_setup <= 32'd50000000; //0.5ms
				end 
				else 
				timer_cnt_setup <= 32'd500000; //1ms
			end
end 

// Receiver Processs
// at every rising edge of the clock
    always @ (posedge clk)
    begin
        if (reset == 1) begin
            rx_clk_count = 0;
            rx_bit_count = 0;
            data_buffer_base = 4'd0;               // base index
            state_rx = 0;
        end
        else begin
//		  data_buffer [0]= 8'hff;
            // if not receive mode and start bit is detected
            if (state_rx == 0 && rxd == 0) begin
                state_rx = 1;       // enter receive mode
                rx_bit_count = 0;
                rx_clk_count = 0;
            end
            // if receive mode
            else if (state_rx == 1) begin
                 
                if(rx_bit_count == 0 && rx_clk_count == CLOCKS_WAIT_FOR_RECEIVE)
					 begin
                    rx_bit_count = 1;
                    rx_clk_count = 0;
                end  
                else if(rx_bit_count < 9 && rx_clk_count == CLOCKS_PER_BIT) 
					 begin
                    rx_data[rx_bit_count-1] = rxd;
                    rx_bit_count = rx_bit_count + 1;
                    rx_clk_count = 0;
                end
                // stop receiving
                else if(rx_bit_count == 9 && rx_clk_count == CLOCKS_PER_BIT && rxd == 1)
					 begin
                    state_rx = 0;
                    rx_clk_count = 0;
                    rx_bit_count = 0;
                     
                    // transmit the received data back to the host PC.
                    data_buffer_rx[data_buffer_base] = rx_data;
					
						  data_buffer_base = data_buffer_base + 1;        // if the index exceeds its maximum, it becomes 0.
						  if(data_buffer_base == 4'd5)
						  begin
						  data_buffer_base = 4'd0;
						  end 
				  end
                // if stop bit is not received, clear the received data
                else if(rx_bit_count == 9 && rx_clk_count == CLOCKS_PER_BIT && rxd != 1) 
					 begin
                    state_rx = 0;
                    rx_clk_count = 0;
                    rx_bit_count = 0;
                    rx_data = 8'b00000000;      // invalidate
                end
                rx_clk_count = rx_clk_count + 1;
            end
        end
         
    end
	 always@(posedge clk)
	 begin
		data_buffer[0] <= 8'h4c;//L
		data_buffer[1] <= 8'h4b;//K
		data_buffer[2] <= 8'h45;//E
		data_buffer[3] <= 8'h4d;//M
		data_buffer[4] <= 8'h42;//B
		data_buffer[5] <= 8'h45;//E
		data_buffer[6] <= 8'h44;//D
		data_buffer[7] <= 8'h44;//D
		data_buffer[8] <= 8'h45;//E
		data_buffer[9] <= 8'h44;//D		 
		
		
		data_buffer[10] <= 8'h42;//B
		data_buffer[11] <= 8'h4C;//L
		data_buffer[12] <= 8'h55;//U
		data_buffer[13] <= 8'h45;//E
		data_buffer[14] <= 8'h54;//T		
		data_buffer[15] <= 8'h4F;//O
		data_buffer[16] <= 8'h4F;//O
		data_buffer[17] <= 8'h54;//T	
		data_buffer[18] <= 8'h48;//H		

		data_buffer[19] <= 8'h54;//T
		data_buffer[20] <= 8'h45;//E
		data_buffer[21] <= 8'h53;//S	
		data_buffer[22] <= 8'h54;//T		
		
		data_buffer[23] <= 8'h0D;//CR	
		data_buffer[24] <= 8'h0A;//LF		
	 end 
	 
	 always@(posedge clk)
	 begin
		data_setup[0] <= 8'h41;//A
		data_setup[1] <= 8'h54;//T
		data_setup[2] <= 8'h0D;//CR	
		data_setup[3] <= 8'h0A;//LF	
		
//		data_setup[4] <= 8'h41;//A
//		data_setup[5] <= 8'h54;//T
//		data_setup[6] <= 8'h2B;//+
//		data_setup[7] <= 8'h52;//R
//		data_setup[8] <= 8'h45;//E
//		data_setup[9] <= 8'h53;//S
//		data_setup[10] <= 8'h45;//E
//		data_setup[11] <= 8'h54;//T 
//		data_setup[12] <= 8'h0D;//CR	
//		data_setup[13] <= 8'h0A;//LF	

		data_setup[4] <= 8'h41;//A
		data_setup[5] <= 8'h54;//T
		data_setup[6] <= 8'h2B;//+
		data_setup[7] <= 8'h4F;//O
		data_setup[8] <= 8'h52;//R
		data_setup[9] <= 8'h47;//G
		data_setup[10] <= 8'h4C;//L
		data_setup[11] <= 8'h0D;//CR	
		data_setup[12] <= 8'h0A;//LF	
		//AT+ORGL restore default ( type=0,code=0x009e8b33, mode=slave, serial=38400,8,N,1, passkey=1234, name=H-C-2010-06-01, ...

		
		data_setup[13] <= 8'h41;//A
		data_setup[14] <= 8'h54;//T
		data_setup[15] <= 8'h2B;//+
		data_setup[16] <= 8'h56;//V
		data_setup[17] <= 8'h45;//E		
		data_setup[18] <= 8'h52;//R
		data_setup[19] <= 8'h53;//S
		data_setup[20] <= 8'h49;//I
		data_setup[21] <= 8'h4F;//O
		data_setup[22] <= 8'h4E;//N
		data_setup[23] <= 8'h3F;//?
		data_setup[24] <= 8'h0D;//CR	
		data_setup[25] <= 8'h0A;//LF	
		
		data_setup[26] <= 8'h41;//A		
		data_setup[27] <= 8'h54;//T
		data_setup[28] <= 8'h2B;//+
		data_setup[29] <= 8'h4E;//N	
		data_setup[30] <= 8'h41;//A		
		data_setup[31] <= 8'h4D;//M	
		data_setup[32] <= 8'h45;//E	
		data_setup[33] <= 8'h3D;//<=		
		data_setup[34] <= 8'h4C;//L
		data_setup[35] <= 8'h4B;//K
		data_setup[36] <= 8'h0D;//CR	
		data_setup[37] <= 8'h0A;//LF
		
		data_setup[38] <= 8'h41;//A		
		data_setup[39] <= 8'h54;//T
		data_setup[40] <= 8'h2B;//+
		data_setup[41] <= 8'h50;//P	
		data_setup[42] <= 8'h53;//S		
		data_setup[43] <= 8'h57;//W	
		data_setup[44] <= 8'h44;//D	
		data_setup[45] <= 8'h3D;//<=		
		data_setup[46] <= 8'h31;//1
		data_setup[47] <= 8'h32;//2
		data_setup[48] <= 8'h33;//3
		data_setup[49] <= 8'h34;//4
		data_setup[50] <= 8'h0D;//CR	
		data_setup[51] <= 8'h0A;//LF	
		
		data_setup[52] <= 8'h41;//A		
		data_setup[53] <= 8'h54;//T
		data_setup[54] <= 8'h2B;//+
		data_setup[55] <= 8'h52;//R	
		data_setup[56] <= 8'h4F;//O		
		data_setup[57] <= 8'h4C;//L	
		data_setup[58] <= 8'h45;//E	
		data_setup[59] <= 8'h3D;//<=		
		data_setup[60] <= 8'h30;//0
		data_setup[61] <= 8'h0D;//CR	
		data_setup[62] <= 8'h0A;//LF
		
//		data_setup[63] <= 8'h41;//A		
//		data_setup[64] <= 8'h54;//T
//		data_setup[65] <= 8'h2B;//+
//		data_setup[66] <= 8'h55;//U	
//		data_setup[67] <= 8'h41;//A		
//		data_setup[68] <= 8'h52;//R	
//		data_setup[69] <= 8'h54;//T	
//		data_setup[70] <= 8'h3D;//=		
//		data_setup[71] <= 8'h39;//9
//		data_setup[72] <= 8'h36;//6
//		data_setup[73] <= 8'h30;//0	
//		data_setup[74] <= 8'h30;//0		
//		data_setup[75] <= 8'h2C;//,	
//		data_setup[76] <= 8'h30;//0	
//		data_setup[77] <= 8'h2C;//,	
//		data_setup[78] <= 8'h30;//0
//		data_setup[79] <= 8'h0D;//CR	
//		data_setup[80] <= 8'h0A;//LF	
		
//		data_setup[14] <= 8'h41;//A
//		data_setup[15] <= 8'h54;//T
//		data_setup[16] <= 8'h2B;//+
//		data_setup[17] <= 8'h41;//A
//		data_setup[18] <= 8'h44;//D		
//		data_setup[19] <= 8'h44;//D
//		data_setup[20] <= 8'h52;//R
//		data_setup[21] <= 8'h3F;//?
//		data_setup[22] <= 8'h0D;//CR	
//		data_setup[23] <= 8'h0A;//LF	
		
//		data_setup[80] <= 8'h41;//A		
//		data_setup[81] <= 8'h54;//T
//		data_setup[82] <= 8'h2B;//+
//		data_setup[83] <= 8'h43;//C	
//		data_setup[84] <= 8'h4D;//M		
//		data_setup[85] <= 8'h4F;//O	
//		data_setup[86] <= 8'h44;//D	
//		data_setup[87] <= 8'h45;//E		
//		data_setup[88] <= 8'h3D;//=
//		data_setup[89] <= 8'h31;//1
//		data_setup[90] <= 8'h0D;//CR	
//		data_setup[91] <= 8'h0A;//LF	
//		
//		data_setup[92] <= 8'h41;//A		
//		data_setup[93] <= 8'h54;//T
//		data_setup[94] <= 8'h2B;//+
//		data_setup[95] <= 8'h50;//P	
//		data_setup[96] <= 8'h4F;//O		
//		data_setup[97] <= 8'h4C;//L	
//		data_setup[98] <= 8'h41;//A	
//		data_setup[99] <= 8'h52;//R		
//		data_setup[100] <= 8'h3D;//=
//		data_setup[101] <= 8'h30;//0		
//		data_setup[102] <= 8'h2C;//,	
//		data_setup[103] <= 8'h30;//0	
//		data_setup[104] <= 8'h0D;//CR	
//		data_setup[105] <= 8'h0A;//LF	
//		
//		data_setup[106] <= 8'h41;//A		
//		data_setup[107] <= 8'h54;//T
//		data_setup[108] <= 8'h2B;//+
//		data_setup[109] <= 8'h49;//I	
//		data_setup[110] <= 8'h4E;//N		
//		data_setup[111] <= 8'h49;//I	
//		data_setup[112] <= 8'h54;//T	
//		data_setup[113] <= 8'h0D;//CR	
//		data_setup[114] <= 8'h0A;//LF	
//		
//		data_setup[115] <= 8'h41;//A		
//		data_setup[116] <= 8'h54;//T
//		data_setup[117] <= 8'h2B;//+
//		data_setup[118] <= 8'h53;//S	
//		data_setup[119] <= 8'h54;//T		
//		data_setup[120] <= 8'h41;//A	
//		data_setup[121] <= 8'h54;//T	
//		data_setup[122] <= 8'h45;//E		
//		data_setup[123] <= 8'h3F;//?
//		data_setup[124] <= 8'h0D;//CR	
//		data_setup[125] <= 8'h0A;//LF	
end 
assign txd = tx_bit;
endmodule
