1
Badge Computer gets battery and mounted
2
Memory controller work continues….workaround 4MB SRAM add-on
3
Cirrus Logic CS4335 DAC problems finally identified and fixed.
4
left-justified DAC problems continue
5
Trying to debug my design for an Audio DAC Cirrus Logic CS4334
6
J68 is now booting from User Flash Memory on the BEMICRO MAX10 FPGA board
7
Still debugging the attachment of User Flash Memory to the J68….
8
LCD Test image and pixel-level detail
9
Reverse engineering the LCD interface
10
J68 boots VUBUG monitor on the BEMICRO MAX 10 FPGA board

Badge Computer gets battery and mounted

latest_hbcx1600

I needed a safe way to transport the badge computer for my trip to/from Hackers on Planet Earth, and so I put this together in typical hacker fashion.

I used  small piece of plywood to mount the components. Trying to find hardware that would work and be safe was pretty tricky, but I decided that this blue painters tape does the job nicely.

You’ll see there’s a couple additions:

  • a 3800mah 7.2v NIMH cell, used for powering this via battery, making it truly portable
  • I’m using a couple of low drop out voltage regulators: LD1117V33 for the 3.3v one, and L4940V5 for the 5.0v one.
  • a FPC extension cable that allows the screen to be remotely connected to the interface board

As many of you probably know, when you use a voltage regulator, you need to account for the drop out voltage. This voltage is the smallest allowable difference allowed between the INPUT voltage (in my case +7.2v) and the desired OUTPUT voltage (which is either +5.0v or +3.3v). Otherwise the voltage regulator fails to regulate.

See wikipedia : https://en.wikipedia.org/wiki/Dropout_voltage and https://en.wikipedia.org/wiki/Low-dropout_regulator

Normal voltage regulators would not work here, because as the NIMH discharges, the voltage continuously drops from a nominal 1.2V(with this battery, in practice a little higher, about 1.36V) per cell, and then drops to 1.0V per cell when it’s exhausted. We are using a 6-cell pack, so this translates to a starting voltage of about 8.2V, and a finishing voltage around 6V.

discharge

If we used a normal 5V voltage regulator like the 7805, whose dropout voltage is as high as 2V, then as soon as we got to 5+2=7V, then we’d fail to have +5V that we could count on. This leaves plenty of battery left, but unusable given those parts.

The L4940V5 low drop out regulator I chose only has a worst-case 900mv dropout. So this gives us until 5.9V. The battery dies at 6V, so this works out perfectly. Now the actual drop out voltage is dependent on the current being pulled through it, with higher currents increasing the dropout voltage. In our case, we don’t need maximum current, which means we won’t be”paying” with the maximum drop out voltage either. The actual dropout voltage is probably closer to 200mv than 900mv.

 

Memory controller work continues….workaround 4MB SRAM add-on

SRAM_parts

SO here’s a couple hundred dollars of SRAM parts ordered to add on to the FPGA. It goes like this: the memory controller isn’t fully integrated yet into the J68 soft-core, so I’ve decided to whack on 4 megabytes of 10-12ns SRAM. SRAM is expensive! About $24 for good quality ISSI ram.

What you see in the center of the image above are three (80) pin card edge MEC6-140 connectors that are designed to mate with the FPGA board. I needed something to mount the SRAM chip (48-pin TSOP I) on and something to mount these 80-pin connectors on. It turns out my closest match are these Schmartboard PCBs, which I’ve wanted to check out for the longest time.

It turns out that I really don’t care for these Schmartboards, partially because I don’t have the right 0.4mm tip required for the pitches, but there’s other reasons. These likely deserve their own review which I will do in a separate post.

It turns out that when you are creating memory boards, you’ve got to deal with a lot of pins. How many? 16 data bits wide, 21 bits of address, plus 5 control pins, oh yeah (2) power and (2) ground as well. So that’s a solid 46 pins you’re using. The 80-pin connector has about (60) usable data pins, so at least the FPGA can support this application.

I do love the fact that the memory I’m using are 10-12ns chips. Really fast access times. Here’s a link to the digi-key part.

Here’s what $75 in memory chips looks like:

just_32mbit_sram

 

Of course you’ve got to create a pinout and hope you get everything right.

Below you’ll see a half-finished board with the 80-pin connector on the right, and the SRAM soldered to the board underneath the wires.

half_wired_boards

I’ve just recently completed the entire board, more photos to come on this.

While a couple initial writes and reads functioned, some reads or writes are failing. I need to write a small state machine that loops through all addresses, and then reads them back to check for errors.

Cirrus Logic CS4335 DAC problems finally identified and fixed.

I had some assistance in fixing this problem. My always helpful friend Brian from Canada as well as some help from Steve @ the Audacity forums contributed to solving the problem. They filled in some blanks for me, and encouraged me to LOOK at the data to see the problem.

This is the “Quit thinking and look” solution found in this book called “Debugging Rules”. Absolutely love this book!! Amazon link.

  • I used Signal Tap II on the Altera FPGA as an internal logic analyzer to see both address values and ROM data values, so that I could correlate them with the serial data going outbound. This was an invaluable tool. There are also tutorials on youtube. Here’s an example of the data I was able to get: (CLICK FOR FULL SIZE)

signaltap_dac

  • I was also able to use my new mixed signal scope to capture the waveforms. The data is 8khz sample rate and 16-bit audio. Check out how nicely spaced these samples are — exactly 125ms apart!

serial_audio_data_scopeshot

  • The data coming out of Audacity’s Export Audio (Header: RAW, Encoding: Signed 16-bit PCM) was the opposite endianness that the DAC was expecting. I switched the bytes from 0xABCD to 0xCDAB and that fixed it.
  • My overall electronic design in Verilog for this was just ugly. And initially did not work — I wasn’t putting the right data on the serial pin at the right time. The right Verilog was ridiculously simple once I distilled it down properly.
  • I’ll post the Verilog with data files once I clean them up a bit. Feel free to email me (contact info above at menu) to nudge me if I haven’t done this yet.
  • I used SRECORD to convert the output of Audacity into a .MIF to load into a virtual ROM on the altera. I could have byte-swapped during the conversion, but currently do it on the FPGA. Either way is easy enough.
  • The initial 700hz tone that I have been fighting with for awhile finally came out alright tonight. It really was music to my ears.

Voice_011 (as a .wav file download or use Embedded Player below)

 

Voice_012 (as an .wav file download, or use Embedded Player below)

  • I added a little more interesting sound below:

left-justified DAC problems continue

Here you see the analog sound waveform coming out of the DAC at the top in yellow.

I think I’m getting closer……I switched from the I2S DAC to a left-justified DAC just because the LJ one is a little simpler to design around….the MSB for the DATA is lined up with the LRCLK transition……

The digital channels below are the input to the DAC:

D3 is the serial data

D2 is SCLK

D1 is LRCLK

D0 is the MCLK

dac_troubleshoot

Latest audio clip:

Trying to debug my design for an Audio DAC Cirrus Logic CS4334

I purchased a CS4334 to eventually use as an Audio DAC for the badge computer. I’ve never worked with DACs before, and my knowledge of audio is somewhat limited.

This audio DAC is a Cirrus Logic CS4334 with datasheet available here.

This chip is the I2S variant, specifically not the LEFT justified or RIGHT justified one. Each variant has slightly different timing requirements. The I2S specification is located here.

The audio data is a simple 700hz tone for 4 seconds with sample rate of 8000hz, and using signed 8-bit export. The audio file is here. 8k_signed8bit_straight700hz4s <— rename the .txt to .aiff. Use “Import Raw” feature of audacity, specify 8000 sample rate, signed 8-bit pcm. I generate an altera .mif using srecord, and here’s the resulting .MIF —–> 8ksigned_700_4s.

Here’s the output that I’m hearing. There are (8) chunks of sound as far as I can tell.

There IS my 700hz sample found in one of those eight chunks. It’s the “purest” sounding chunk of sound. You’ll know it as soon as you hear. LINK if the player below doesn’t work for you.

Any help to what the heck I’m doing wrong here would be appreciated!!

Here’s my verilog:

dac_clocks dac_clocks_inst (
.areset ( 1'b0 ),
.inclk0 ( SYS_CLK ),
.c0 ( SCLK ),
.c1 ( LRCLK ),
.c2 ( MCLK ),
.locked ( USER_LED[1] )
);

reg [7:0] sendbyte;
wire [7:0] romout;
reg [13:0] address;

reg SDATA;
wire SCLK; //128khz
wire MCLK; //1.024mhz
wire LRCLK; //8000hz to match the sample rate

assign PMOD_B[0] = SDATA;
assign PMOD_B[1] = SCLK;
assign PMOD_B[2] = LRCLK;
assign PMOD_B[3] = MCLK;

//setup the edge detection for LRCLK
reg LRCLK_OLD;

always @(posedge MCLK)
begin
LRCLK_OLD &lt;= LRCLK;
end

assign LRCLKfalledge=LRCLK_OLD & !LRCLK;
assign LRCLKriseedge=!LRCLK_OLD & LRCLK;

dacrom dacrom_inst (
.address ( address ),
.clock ( MCLK ),
.q ( romout )
);

/*this is to satisfy "In I2S mode, the MSB of the left channel is valid on the second rising
edge of BCLK[my SCLK] after the falling edge of LRCLK. Similarly, the MSB of the right channel is valid on the
second rising edge of BCLK after the rising edge of LRCLK"
*/


reg [7:0] twocycledelay;
always @(posedge LRCLKfalledge or negedge SCLK)
begin
if (LRCLKfalledge) twocycledelay <= 8'b0;

if (!SCLK) begin
twocycledelay <= twocycledelay + 8'b1;

if (twocycledelay == 8'd2) begin

sendbyte <= romout;
//counter <= 3'b0; //reset the bitcounter because we have a new byte

end
//else counter <= counter + 3'b1; //send next bit if we're not resetting

end

end

always@(posedge LRCLKfalledge) //when it's true that there's a falling edge, read the next byte
begin
address <= address + 14'b1;
if (address == 14'd32000) address <= 14'b0; //data in rom is 32000 bytes deep
end

reg [2:0] counter;

//send data MSB first. is it already two's complement from audacity?
always@(negedge SCLK) //put the data on the falling edge so that the receiver can read it on rising.
begin

SDATA <= sendbyte[3'd7-counter];
counter <= counter + 3'b1;
end
[/pre]

J68 is now booting from User Flash Memory on the BEMICRO MAX10 FPGA board

I’ve been struggling for quite a few nights and weekends over the last month or so.

I’ve now successfully attached the J68 to the built-in User Flash Memory. This means that the 16KB (actually about ~13KB) of the ROM monitor VUBUG is now out of the pre-initialized m9k’s configured as a ROM, and now into FLASH. Which is non-volatile, and will survive a reboot. The most important part of this is that it frees up our valuable high-speed on-chip m9k’s.

The solution involved waiting for rd_ena (read enable) to go high, and combining that with the address that makes it a ROM READ, and then passing that to the Altera IP Flash avalon-mm bus interface. Since the latency is a fixed-cycle delay, then I just shift that read-enable pulse to become the “data is ready pulse”, aka data_ack and feed that back to the J68.

I had some more complicated solutions including a state machine, but this way is clearly superior. I had created some bolt-on hardware to help troubleshoot the problem. While it helped initially, when I had the problem fixed, some symptoms in the add-on hardware hid the fact that it was actually working….

The SDRAM controller works in simulation when connected to the J68, and hopefully will be tested on hardware very soon. This puts the ROM code in FLASH, and the RAM on the 8MB memory chip where it belongs. This will give us what we need for future development, including the GPU!

Still debugging the attachment of User Flash Memory to the J68….

So if I take my working UFM avalon-mm Master controller (which if you recall, connects to the Altera Flash Memory IP core), and attempt to attach it to the J68, the J68 no longer boots the ROM monitor code.

Since it’s not booting, I really don’t have many indications as to why. I decided that writing a ROM bus sniffer that records ROM memory requests and responses, including how long it took to satisfy that request, was worth the trouble.

In the image below, you’ll see four 32-bit columns of data on the left. Each row is a separate request.

They are:

  • A 32-bit counter that increments once a master clock cycle. Right now, I’m just running at 33.333mhz, but this J68 works upwards to 100mhz. This is recorded at the time of the request — at the time rd_ena goes high.
  • The ROM memory address being requested (first column on the left in BLUE)
  • The 32-bit counter at the time data_ack goes high, which means the request has been handled
  • The actual 16-bit data value. Ignore the 0xFAFA — that’s just padding. (rightmost column in BLUE)

ROM_debugger

Note that the requests are being handled the next clock cycle, right now, with the M9k’s serving up the ROM file. So you see 0x3A request, 0x3B response. 0x40 request, 0x41 response, and so on. The flash will not be as quick, and there should be something like (5) cycles between them.

My plan is to attach my newly working debugger to the new J68 solution with the UFM, and compare it. I think the problem will be obvious once I see what is happening…..

LCD Test image and pixel-level detail

So I’ve managed to get a semi-working test pattern image up on the LCD.

Here are a couple shots:

badge_Test

If we zoom in about 10 times, we can see how the LCD really works, on an individual pixel level:

lcd_pixels_small

Pretty challenging to get a decent image out of this, but here you can see the individual LEDs that make up the TFT screen that we’re using….. Interesting that the roughly-purple color comes from Blue and Red mixed…. except they aren’t mixed, just very close together.

From http://www.inteltronicinc.com/aa_4.asp?nid=10

Here’s an idealized image…..looks pretty similar to mine!

RGB_image

I actually don’t think that the colors above in my test image are right….there seem to be documentation problems for the pinouts on the BEMICROMAX10…….

Reverse engineering the LCD interface

So I was having trouble getting the LCD working initially, so I ended up probing a working HDMI to LCD converter board sold by adafruit. You see, this board was driving my LCD just fine, but my FPGA couldn’t do diddly. So I wanted to see what I was missing.

This proved more difficult because of these 40-pin FPC connectors. Not sure what the pitch is, but it’s really freakin’ close together.

With a lighted magnifier (3x diopter?), and sharp o’scope probe, I was able to isolate individual pins on the 40-pin, long enough to hit the stop button on the scope.

oscope_hdmilcd

What you see on the screen is (likely) the probing of the HSYNC pin, showing the pulse in between each line. So between pulses, you’d have 800 pixels worth of video data.

I’ll post the LCD and associated required timing specs once I get everything working 100%, but I’m over the hurdles.