Jump to content
  • 0

Digilent Ambient Light Sensor not working


magictaro

Question

Hello

I'm using BASYS2 at Digilent Co.

and Studying Ambient Light Sensor Pmod.

I think below source code is correct, but not working on my board.

 

clk : 50Mhz

sclk : 1Mhz

cs : sclk x 16 count

data 8bit ( dout is 1bit data)

LED : output and check of information by Ambient Light Sensor

 

My source code is below.

but it's not working on BASYS2 board.

(I did and saw test bench simulator, but there is correct output pulse LED etc)

I don't know what is error . So Please some imformation or advice

 

 

 

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;


ENTITY SPI3 IS
PORT(
clk : IN std_logic;
clr : IN std_logic;
dout : IN std_logic;
led : OUT std_logic_vector( 7 DOWNTO 0 );
sclk : OUT std_logic;
cs : OUT std_logic
);
END SPI3;

ARCHITECTURE SPI3_be OF SPI3 IS

TYPE state_type IS( idle, adc_r, adc_w );
SIGNAL state : state_type := idle;

SIGNAL cnt_sclk : INTEGER RANGE 0 TO 49;
SIGNAL newsclk : std_logic := '0';
SIGNAL cnt_cs : INTEGER RANGE 0 TO 1599;
SIGNAL newcs : std_logic := '1';
SIGNAL data : std_logic_vector( 7 DOWNTO 0 );
SIGNAL cnt_data : INTEGER RANGE 1 TO 16;

BEGIN
sclk <= newsclk;
cs <= newcs;

clkdiv : PROCESS( clr, clk )
BEGIN
IF clr = '0' THEN
cnt_sclk <= 0;
cnt_cs <= 0;
newsclk <= '0';
newcs <= '1';
ELSIF clk'EVENT AND clk = '1' THEN
IF cnt_sclk = 49 THEN
newsclk <= NOT newsclk;
cnt_sclk <= 0;
ELSE
cnt_sclk <= cnt_sclk + 1;
END IF;

IF cnt_cs = 1599 THEN
newcs <= NOT newcs;
cnt_cs <= 0;
ELSE
cnt_cs <= cnt_cs + 1;
END IF;
END IF;
END PROCESS clkdiv;

 

FSM : PROCESS( clk, clr, state )
BEGIN
IF clr ='0' THEN
cnt_data <= 1;
data <= "11111111";
ELSIF clk'EVENT AND clk = '1' THEN
CASE state IS
WHEN idle =>
IF newcs = '1' THEN
state <= idle;
ELSIF newcs ='0' THEN
state <= adc_r;
END IF;

WHEN adc_r =>
IF cnt_data >0 AND cnt_data <4 THEN
cnt_data <= cnt_data + 1;
state <= adc_r;
ELSIF cnt_data > 3 AND cnt_data <12 THEN
cnt_data <= cnt_data + 1;
data( 11 - cnt_data ) <= dout;
state <= adc_r;
ELSIF cnt_data > 11 AND cnt_data <16 THEN
cnt_data <= cnt_data + 1;
state <= adc_r;
ELSIF cnt_data = 16 THEN
state <= adc_w;
END IF;

WHEN adc_w =>
led <= data;
cnt_data <= 1;
state <= idle;

END CASE;
END IF;
END PROCESS FSM;
END SPI3_BE;

Link to comment
Share on other sites

2 answers to this question

Recommended Posts

The problem is that you are sampling the spi signal at clk and not sclk. You probably got an output that looked like all the leds were doing the same thing. If so, you were most likely picking up a single data bit. The fix is to change all the clk to sclk in you state machine. The code I ended up is below.

Other things I did included flipping the polarity of the clr signal since I just used a button. Also I removed the pullup identifiers for the Pmod pins in my UCF since SPI doesnt require them. 

Ill keep an eye on the page in case you need any more help!

-Sam


 

 

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;
USE IEEE.std_logic_unsigned.ALL;


ENTITY SPI3 IS
PORT(
clk : IN std_logic;
clr : IN std_logic;
dout : IN std_logic;
led : OUT std_logic_vector( 7 DOWNTO 0 );
sclk : INOUT std_logic;
cs : OUT std_logic
);
END SPI3;

ARCHITECTURE SPI3_be OF SPI3 IS

TYPE state_type IS( idle, adc_r, adc_w );
SIGNAL state : state_type := idle;

SIGNAL cnt_sclk : INTEGER RANGE 0 TO 49;
SIGNAL newsclk : std_logic := '0';
SIGNAL cnt_cs : INTEGER RANGE 0 TO 1000;
SIGNAL newcs : std_logic := '1';
SIGNAL data : std_logic_vector( 7 DOWNTO 0 );
SIGNAL cnt_data : INTEGER RANGE 1 TO 16;

BEGIN
sclk <= newsclk;
cs <= newcs;

clkdiv : PROCESS( clr, clk )
BEGIN
IF clr = '1' THEN
cnt_sclk <= 0;
cnt_cs <= 0;
newsclk <= '0';
newcs <= '1';
ELSIF clk'EVENT AND clk = '1' THEN
IF cnt_sclk = 49 THEN
newsclk <= NOT newsclk;
cnt_sclk <= 0;
ELSE
cnt_sclk <= cnt_sclk + 1;
END IF;

IF cnt_cs = 1000 THEN
newcs <= NOT newcs;
cnt_cs <= 0;
ELSE
cnt_cs <= cnt_cs + 1;
END IF;
END IF;
END PROCESS clkdiv;

 

FSM : PROCESS( sclk, clr, state )
BEGIN
IF clr ='1' THEN
cnt_data <= 1;
data <= "11111111";
ELSIF sclk'EVENT AND sclk = '1' THEN
CASE state IS
WHEN idle =>
IF newcs = '1' THEN
state <= idle;
ELSIF newcs ='0' THEN
state <= adc_r;
END IF;

WHEN adc_r =>
IF cnt_data >0 AND cnt_data <4 THEN
cnt_data <= cnt_data + 1;
state <= adc_r;
ELSIF cnt_data > 3 AND cnt_data <12 THEN
cnt_data <= cnt_data + 1;
data( 11 - cnt_data ) <= dout;
state <= adc_r;
ELSIF cnt_data > 11 AND cnt_data <16 THEN
cnt_data <= cnt_data + 1;
state <= adc_r;
ELSIF cnt_data = 16 THEN
state <= adc_w;
END IF;

WHEN adc_w =>
led <= data;
cnt_data <= 1;
state <= idle;

END CASE;
END IF;
END PROCESS FSM;
END SPI3_BE;

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...