//   ==================================================================
//   >>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<
//   ------------------------------------------------------------------
//   Copyright (c) 2022 by Ampelsteuerungsgruppe
//
// --------------------------------------------------------------------
//
//  Project:           iCE5UP 5K RGB LED Steuerung
//  File:              LED_control.sv
//  Title:             LED Ampelsteuerung
//  Description:       Creates RGB PWM per data input
//                 
//
// --------------------------------------------------------------------
//
//------------------------------------------------------------
// Notes:
//
//
//------------------------------------------------------------
// Development History:
//
//   __DATE__ _BY_ _____REV_ _DESCRIPTION___________________________
//   17.02.22  AmpelGr  1.0    Initial design for Lattice Radiant Ampelsteuerung
//
//------------------------------------------------------------
// Dependencies:
//
// 
//
//------------------------------------------------------------


module LED_control1 (
        // inputs
        input   wire    clk12M,        		// 12M clock
		input 	wire 	enable,             // Asynchronous enable/disable wire
        input   wire    [7:0] data_input,  	// for selecting color using sensor data
		input 	wire 	data_valid,			// Data on Parallelport is valid on posedge
        //outputs
        output reg  red_pwm,       	// Red LED
        output reg  grn_pwm,       	// Green LED
		output reg	alarm			// Alarmmeldung
        );


//------------------------------
// INTERNAL SIGNAL DECLARATIONS: 
//------------------------------
// parameters (constants)
parameter     on_hi = 2'b10;
parameter     on_lo = 2'b01;
parameter     off   = 2'b00; 
parameter Brightness=4'b0111; //50% Brightness

// wires (assigns)
wire   [4:0] red_intensity;
wire   [4:0] grn_intensity;
wire clk24M;
wire LOCK;

// regs (always)
reg     [1:0] RGB_color_s;    		// selected Color    
reg     [3:0] Brightness_s;              

reg     [1:0] red_set;		  		// hi/lo/off
reg     [1:0] grn_set;		  	  

reg    [17:0] red_peak;		  		// LED 'on' peak intensity (high precision)
reg    [17:0] grn_peak;

reg     [17:0] curr_red;			// current LED intensity ( /256 = PWM duty cycle)
reg     [17:0] curr_grn;

reg     [17:0] pwm_count;           // PWM counter
reg [7:0] count = 8'b0;

//------------------------------
// PLL Instantiation
//------------------------------
//Block to reset the PLL initially

pll_24M __(.ref_clk_i(clk12M ), .rst_n_i(~enable), .lock_o(LOCK), .outcore_o( ), .outglobal_o(clk24M));


//   Capture stable parameters in local clock domain
always @ (posedge clk24M or posedge enable)
    if (enable) begin
      RGB_color_s   <= 2'b00;	//turn off
      Brightness_s  <= 4'b0000;
	  alarm <= 0;
    end else if(!alarm) begin
		if(data_valid) begin
			if(data_input <100) begin
				RGB_color_s <= 2'b10; // set green
				Brightness_s  <= Brightness;
			end else if(data_input >168) begin
				alarm <=1'b1;
			end else begin
				RGB_color_s <= 2'b11; // set yellow
				Brightness_s  <= Brightness;
			end
		end
    end else begin   
      RGB_color_s   <= 2'b01; // set Color red
      Brightness_s  <= Brightness;
    end


// interpret 'brightness' setting
assign red_intensity =  Brightness_s + 1'b1;
assign grn_intensity = Brightness_s + 1'b1;


// interpret 'color' setting
always @ (RGB_color_s)	 
  case (RGB_color_s)
    2'b01:   begin red_set   <= on_hi; grn_set   <= off;    end //Red
    4'b10:   begin red_set   <= off;   grn_set   <= on_hi;  end //Green
    4'b11:   begin red_set   <= on_hi; grn_set   <= on_hi;  end //Yellow
    default: begin red_set   <= off;   grn_set   <= off;    end //2'b00 off
  endcase

// set peak values per 'brightness' and 'color'
//   when color setting is 'on_lo', then peak intensity is divided by 2
always @ (posedge clk24M or posedge enable)
    if (enable) begin
      red_peak <= 18'b0;
    end else begin
      case (red_set)
        on_hi:  red_peak <= {red_intensity, 13'h000};       // 100%
        on_lo:  red_peak <= {1'b0,red_intensity, 12'h000}; // 50%
        default: red_peak <= 18'h00000;
      endcase
    end
    
always @ (posedge clk24M or posedge enable)
    if (enable) begin
      grn_peak <= 32'b0;
    end else begin
      case (grn_set)
        on_hi:  grn_peak <= {grn_intensity, 13'h000};       // 100%
        on_lo:  grn_peak <= {1'b0,grn_intensity, 12'h000}; // 50%
        default: grn_peak <= 18'h00000;
      endcase
	  //$monitor("grn_peak=%d",grn_peak);
    end

// set PWM duty cycle. 8-bit resolution 0x100 is 100% on
always @ (posedge clk24M or posedge enable)
    if (enable) begin
	  curr_red <= 18'b0;
      curr_grn <= 18'b0;
    end else begin
        curr_red <= red_peak;
        curr_grn <= grn_peak;
        end

// generate PWM outputs
always @ (posedge clk24M or posedge enable)
    if (enable) begin
      pwm_count <= 18'b0;
      red_pwm   <= 0;
      grn_pwm   <= 0;
    end else begin
      if(pwm_count < 131071)
        pwm_count <= pwm_count + 1;
      else
        pwm_count <= 0;
      
      if(pwm_count < curr_red)       
        red_pwm <= 1;
      else
        red_pwm <= 0;

      if(pwm_count < curr_grn)
        grn_pwm <= 1;
      else
        grn_pwm <= 0;
		
    end


endmodule // LED_control