Hi guys, Since UFM in the Machxo2 seems to difficult to setup, I broke
out the arduino and with a little help figured out how to write 2 bytes
to memory and read those bytes, i also downloaded Lothar Miller's Spi
Master and got it talking to an spi encoder by a single 16 bit transfer
on the Machxo2. Now the hard part, to read my 2 bytes i have to send
Ox-D2,00,00,00,00,00,00,00,00+ read byte1, 00 + read byte2. To write
those 2 bytes I have to send 0x82, 00,00,00, my byte, my byte. I know i
need to build a state machine, i need ChipSelect to stay low durring the
whole transfer. this one is a little tougher.
Chris C. wrote:> I know i need to build a state machine,
Keep things simple and don't worry about big names: each counter is a
state machine...
> i need ChipSelect to stay low durring the whole transfer.
That easy: you must control SS in your own FSM. Set it low in the first
state and set it high after the last...
> this one is a little tougher.
It istn't. Its just about learning.
First step is to set up a "top level" module and to use the SPI unit as
a component inside your top level entity. Then you control that SPI
module with those three ports you commented out:
-- TX_Data : in STD_LOGIC_VECTOR (length-1 downto 0); -- Send data
-- TX_Start : in STD_LOGIC;
-- TX_Done : out STD_LOGIC;
In that new top level FSM you simply set up TX_Data and set TX_Start to
'1'. Then in the next state you set TX_Start to '0' and wait for TX_Done
to go '1'. If so, you set up TX_Data and set TX_Start to '1' and so
forth...
ive been trying similar code, with mine i was only getting d2 and 2x00
bytes out then it would reset,not sure why. With the the one you just
posted, im getting all of the clocks and cs is working, but no d2 on
mosi.
I Figured it out! TX_DONE was 3 clock pulses wide, so i sent it through
a single edge detector and voila, everything is showing perfectly out to
the logic analyzer!
tx_done <= flipflops(0) and not flipflops(1);
------ Administration --------
PROCESS(clk) -- single edge based interupt
BEGIN
IF rising_edge(clk) THEN
flipflops(0) <= tx_done1;
flipflops(1) <= flipflops(0);
END IF;
END PROCESS;
Chris C. wrote:> This time I switched a few things around and got it to throw out My xd2,> but only 3 bytes follow till it resets back to xd2?
You are right. Run a simulation on it. Then you will see the problem
easily...
It is a problem in handshaking. After a minor chage it looks ok (see
Waveform from simulation):
1
:
2
:
3
whenspi_etx=>
4
SS<='1';-- disable Slave Select
5
TX_Done<='1';
6
-- if(TX_Start = '0') then
7
spitxstate<=spi_stx;
8
-- end if;
9
endcase;
10
:
11
:
Chris C. wrote:> I Figured it out! TX_DONE was 3 clock pulses wide, so i sent it through> a single edge detector
You are right: a workaround can also fit things together... ;-)
Thank YOU Lothar, one last thing, how can i reduce the delay between
bytes? right now from CS to CS is 4.42uS, i can shave off nearly 1uS by
removing some delay between bytes, Im limited to the 50mhz clk due to
all of my other process's in this project are timed with 50mhz, Far
toooo much to go back and recode. I have the Spi Clock at 25mhz, maxed
out.
Ahh, I see, I could also switch to 16 bit instead of 8 and cut it down
by 400ns.
Chris C. wrote:> how can i reduce the delay between bytes?
At the moment these is one "SCLK idle cycle" hidden in the spitxstate
FSM. MAybe you get rid of that by setting the delay in spi_stx to 0:
1
if(TX_Start='1')then
2
spitxstate<=spi_txactive;
3
SS<='0';
4
delay<=0;-- clock_delay; -- clock_delay adds a SCLK idle cycle here...
5
endif;
> I have the Spi Clock at 25mhz, maxed out.
Up to now you use 2.5MHz...
For a 25MHz SPI clock you will need no prescaler at all, because with
every 50MHz clock the SPI clock must be toggled. You will have to look
close at the bit timing at this edge of speed.
So sending and recieving is working, as long as im not trying to put
rx_reg into a "byte", strangely if i add "adjuster0 <= rx_reg;" right
after If tx_done = '1' then, suddenly i dont even get a response from
the flash, as seen on the logic analyzer.