Closed juanjzv closed 6 years ago
Well it's just an arbitrary value I chose when I was first designing this, as I needed to slow down the 50MHz system clock (you could also use a PLL for this). The max7219 specs say it has a 10MHz serial interface, so you could possibly set the clk_div to 2 (to get division by 6 and as a result: a 8.33MHz clock) and everything should work fine.
Just remember that usually to get the high-clock rates you also have to feed it around 5V (VDD), so if you intend to use it with smaller voltages, make sure to also slow the clock down (I guess 1MHz should be ok for 3.3V).
Also note that I'll be revising this code soon, since it was written a long time ago and while it works, it could be made a lot simpler. It was one of my first practical projects in VHDL, so there are some rookie mistakes and confusing choices (like the clock divider).
A more recent version of the "virtual clock" module looks like this: clock_divider.vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity clock_divider is
GENERIC (
denominator : UNSIGNED(25 downto 0) := to_unsigned(42, 26) -- 50 MHz -> 1.19 MHz
);
PORT (
clk_in : IN STD_LOGIC;
clk_out : OUT STD_LOGIC := '0'
);
END entity;
clock_divider_a.vhdl
architecture arch of clock_divider is
begin
CLK_DIVIDER: process(clk_in)
constant div_cnt : unsigned(24 downto 0) := denominator(25 downto 1);
variable cnt : unsigned(24 downto 0) := (others => '0');
begin
if rising_edge(clk_in) then
cnt := cnt + 1;
if cnt = div_cnt then
cnt := (others => '0');
clk_out <= not clk_out;
end if;
end if;
end process;
end arch;
and you can use it like this (provided you put the above in the "utils" library):
khz_clock : entity utils.clock_divider -- 500kHz
GENERIC MAP (denominator => to_unsigned(100, 26))
PORT MAP (clk_in => CLOCK_50, clk_out => CLK_0M5);
Thank you, I should've supposed that clock_50 meant a 50MHz clock. I'm a rookie in vhdl and fpga's and your answer was very helpful. Sorry if I'm making obviuos questions, but although I've almost understood all the project, it seems that in spi_master when a transaction is ended, busy (that goes directly to LED_CS) is then unset in order to latch the data at the shift register in the max7219, but the data sheet says data is latchen on rising edge of CS ( called LOAD for max7219 and !CS for max7221), but 'busy' was set to 0. I don't know if it's me the one that is not understanding the workflow of the architecture or if the LED matrix module with hasthe matrix7219 and the LED matrix in a circuit board also has an inverter for the CS pin. Again, thanks in advance.
Ok, scrap what I wrote previously about LOAD. I forgot that I was using a breakout board (this one), so possibly that is why the signal is inverted. Just define an intermediate signal, and use the inverted value of the busy signal from spi_master like so:
...
signal spi_busy : std_logic := '0';
begin
CS <= not spi_busy;
spi_driver : entity work.spi_master GENERIC MAP (slaves => 1, d_width => 16) PORT MAP (
clock => CLOCK_50, enable => enable, busy => spi_busy, cont => '0',
reset_n => '1', cpol => '0', cpha => '0', addr => 0,
tx_data => data, miso => 'Z', mosi => DIN, sclk => CLK, clk_div => 5
);
...
Thaks for the answer, sorry about delaying mine. I used a breakout board too, when I tested your code, it worked perfectly. After that I was coding a version which allowed me to display a marquee on more than one matrix, and I assigned inverted values to the busy signal and it's working too. Kind of weird, maybe it was just because I dind't have much time to complete it and missed some details. Anyway, the true is that your code works and it was very helpful for me to understand how the Max7219 works.
Well that's great to hear. I don't have any ideas why the inverted value was required for a multi-display setup. I tested it that way as well, and I believe it worked without any changes other than the bus width obviously. Anyway I'm glad I could help :)
This is my first time working with the max7219, and I can't figure out why virtual clock toggles every 43 times the system clock does. I would really aprrecciate any help. Thanks in advance.