Micron/Aptina MT9D131 JPEG Camera

Hi all,

I have been following a similar thread on here that is looking at a JPEG camera from Toshiba, but due to poor documentation, I have decided to try my luck with the MT9D131 JPEG camera from Aptina. The camera is easily available off the shelf and has great documentation.

I am building a camera system from scratch, and so far I am controlling the sensor with a PIC18f420 microcontroller and buffering the data through an AL440B FIFO chip from averlogic. I am curious if anybody has used this sensor before, b/c when I look at the data that I get while running JPEG compression, it doesn’t contain any of the standard JPEG header info.

Any help would be greatly appreciated. Thanks.

Hi Aerospace,

we use MT9D131.

As it’s said in the MT9D131 Developer guide: ‘JPEG data stream sent to the host does not have a header’. You have to create it and attach it to the file you get from the camera in order to get the complete JPEG file. You have the code at the end of Developer guide.

I have some problems with camera configuration. Uncompressed image works fine. But when I set the registers in order to get JPEG image, I get a really small file (about 10kB). Could you please write your register configuration that gives you a compressed image? What’s the input clock you provide to the camera?

Thank you in advance.

vjcro,

The person working on this is on vacation. He will get back to you soon though. I work with him managing the project. Can you say more about how you go the uncompressed image out of the chip? I am not sure we have been that far.

Also, we ordered a $1200 Aptina development board with software. That software came with examples that run off the Blackfin processor which controls the camera. However, the source code provides the register camera register settings. Do you have or need this code?

Hi,

we connected the PCB with camera chip to a PCB with a FPGA and RAM. So, the FPGA collects the image and stores it to RAM.

We also ordered the devcamera from Aptina in order to make our development easier. We downloaded from their website Devware with generic suite. We didn’t find any examples. We don’t use Blackfin processors though, but I would appreciate if you could send it to me. It could be useful, maybe.

We wanted to check the register states in Dewvare. But we noticed that some (quite important) don’t match with the datasheet instructions.

We also tried to connect our PCB camera with Aptina’s controller board (we designed an adapter PCB), but Devware doesn’t recognize our camera.

As you can see, each step in the debugging process has given as more headache :frowning:

I hope we can compare our experiences and find out some useful stuff.

vjcro,

We can talk the week of 1/4.

vjcro,

Hi, I’m the one that has been working with the MT9D131.

  1. We use a 10 MHz input clock, 3 V p-p

  2. Our register settings mostly match the ones used in the Devware software. I was a little confused at first when looking at them, but I am fairly certain that the SOC registers are updated automatically from the virtual drivers when the context is changed. I had to look at those and not the actual registers, since I could only ever see them for Context A. I am going to be in the office tomorrow and will post the settings I use. But note, I haven’t gotten a valid picture yet (not sure if its the header or invalid data).

  3. Can you post a link to the Development guide you mentioned? I have not seen this and would like to look at the header generation code you referenced at the end of the guide.

  4. What register settings did you use to get uncompressed images? (I have been focusing solely on JPEG, and getting a valid uncompressed image would help debug, however I don’t want to reinvent the wheel if I can help it :smiley: )

Hi Aerospace,

we also have a 10 MHz input clock and use PLL.

The Development Guide is not available on the web, you have to log in to Aptina’s pages and request a permission to download it. However, if you want, I can e-mail it to you, just write your e-mail address.

I will post the register settings for uncompressed image ASAP (probably on Monday).

P.S. Best wishes for the new year!

vjcro

Hi, Aerospace,

it took me a while longer to write here again, sorry.

Here are the register settings we use to get a 1000x1000 uncompressed still image:

R0x0A:0 = 0x0002

R0x0D:2 = 0x0007

R0x0A:2 = 0x0001

R0x09:1 = 0x0009

seq.captureParams_mode = 0x02
mode.mode_config = 0x0030
mode.output_width_B = 1000
mode.output_height_B = 1000
mode.crop_X0_B = 300
mode.crop_X1_B = 1300
mode.crop_Y0_B = 100
mode.crop_Y1_B = 1100
seq.cmd = 2
Please let me know does it work for you and what’s your progress.
vjcro

Hey vjcro,

Sorry to get back so late, I was out for the holidays.

Thanks for the register setttings. Im a little confused, though. doesn’t

seq.captureParams_mode = 0x02 set it to capture video?
Also how many bytes were your still images (so I know how many to grab from our FIFO) and what format is it? Bayer 10 bit, RBG565, etc? And what program did you use to view the images after capture?
Here are the settings I used for JPEG capture (some just verify the defaults:
R0x05:0 = 0x0204 'H-blanking (context B)
R0x06:0 = 0x0020 'V-blanking (B)
R0x09:0 = 0x0007 'Shutter Width
R0x0A:0 = 0x0131 'pixel clock timing
R0x0B:0 = 0x03BB 'Extra delay
R0x20:0 = 0x0300 'Read mode for context B
R0x65:0 = 0x2000 'Clock control (enable PLL)
R0x66:0 = 0x4F07 'PLL params
'Color Pipeline (page 1)
R0x08:1 = 0x01F8 'Pipeline control
R0x0B:1 = 0x00DF 'Enable Internal Clocks
R0x09:1 = 0x000A 'Disable output bypass (output JPEG)
'JPEG + FIFO (page 2)
R0x0A:2 = 0x0000 'Disable JPEG bypass

Here are the driver variable settings I used:

seq.captureParams_mode = 0x00

seq.captureParams_numFrames = 0x01

mode.outputWidth_B = 1600 (0x0640)

mode.outputHeight_B = 1200 (0x04B0)

mode.mode_config = 0x0010

mode.FIFO_config0_B = 0x0046 (adaptive clk on, no spoof)

jpeg.format = 0x00

jpeg.config = 0x0034

jpeg.restartInt = 0x0000

The restartInt I found is very important. If this variable is set to zero you must remove the restart interval section of the JPEG header. Else you must make sure that the value in the header matches the value you put in this variable (I believe the default is 0).

I am able to get garbled images with these settings, with no consistency, however I don’t think the problem is with the sensor but rather the architecture I designed around it. Im curious to hear how this works for you, since you have already proven that your architecture works.

Also note, the number of bytes of JPEG data the sensor produced for the last frame is available in the status registers (R0x02:2 and R0x03:2 I believe). You said your files were small, but do they at least match the size found in these registers?

Aerospace:
Im a little confused, though. doesn’t

seq.captureParams_mode = 0x02 set it to capture video? [/quote]
You’re right, but it wasn’t actually so important for our implementation, because we turn the camera off after the first frame (after FV signal falls). But I will change it, to make things more clean.
1000x1000 image is 2 000 000 bytes, format is YUV, 2B per pixel, 8 bit output. Quite a lot, I know, but you can also capture a smaller image just for verification.
The image is collected via RS232 and we have a Matlab script to convert the .txt file from YUV image to RGB and then we can see the image on screen.
We also noticed the importance of restartInt.
Our main problem is that we implemented I2C register configuration in FPGA. But we didn’t implement the I2C reading. That’s why we can’t check state of any register. We kind of hope to have made the right configuration… The next step for our development is to implement I2C configuration (and registers verification!) in a microcontroller and only leave image collection to the FPGA.
I’m quite busy with some other stuff these days, but I have to continue the work on the camera asap. I’ll study more carefully your registers and everything else you wrote and then I’ll be back in touch.

Sounds good, let me know what you find out.

Also, would you mind sending me the Matlab script? I can pm you my email address if need be. I am trying to eliminate all possible sources of error, so running a script thats already been used would help speed things along a lot.

Thanks again for all the help.

No problem, send me you e-mail address in pm and I’ll send it tomorrow.

Update:

I was able to obtain valid uncompressed images using the settings you posted (w/ smaller image sizes)

I tried switching to JPEG, but had no luck. I am generating my header based off of the sample code in the developer’s guide (except for the Huffman tables, I am just using what I think are standard values, but updating this is my next step). I am able to grab the right number of bytes from the camera though (based on registers 0x02:2 and 0x03:2).

Thats all for now, not sure if the problem is in my header or my data, or how to check this. Any thoughts?

Ok, than it turns out your HW surrounding is more stable than ours for now.

I’ve been getting 960 000 large files lately (with this configuration I wrote and also for a smaller image). I suppose the problem is I2C, so I’ve been dealing with that these days. It takes me longer cause I’m using a Bitcloud stack, and I didn’t figure completely out yet how to get I2C going on it.

This is the configuration we’ve used earlier to get JPEG image:

R0x66:0 = 0x1801 //PLL setup, M = 24; N = 1; P = 0; f_in = 10 MHz, f_out = 60 MHz

R0x67:0 = 0x0000

R0x65:0 = 0xA000

R0x65:0 = 0x2000

R0x0A:2 = 0x0000 // Disable JPEG encoder bypass

R0x09:1 = 0x000A //DATA output - use FIFO

seq.captureParams_mode = 0x00 //capture still image
mode.mode_config = 0x0000 //Use JPEG compression
– JPEG config
jpeg.qscale1 = 0x89
jpeg.restartInt = 0x0020
– Image cropping and scaling
mode.output_width_B = 900
mode.output_height_B = 900
mode.crop_X0_B = 350
mode.crop_X1_B = 1250
mode.crop_Y0_B = 150
mode.crop_Y1_B = 1050
– change context to capture
seq.cmd = 2
At some point we managed to get a solid image (in a sense that you could see the proper scene), but with black lines in random places, as if something went wrong with JPEG. For some reason, we can’t get even that any more.
So, try this (maybe it’ll need some adjustments to your system) and tell me what you get.

vjcro:
Hi Aerospace,

we use MT9D131.

As it’s said in the MT9D131 Developer guide: ‘JPEG data stream sent to the host does not have a header’. You have to create it and attach it to the file you get from the camera in order to get the complete JPEG file. You have the code at the end of Developer guide.

I have some problems with camera configuration. Uncompressed image works fine. But when I set the registers in order to get JPEG image, I get a really small file (about 10kB). Could you please write your register configuration that gives you a compressed image? What’s the input clock you provide to the camera?

Thank you in advance.

vjcro,

As I am interested in JPEG camera as well, can you email me the MTD131 Developers Guide? - janek[at]bigpond[dot]net[dot]au

I have filled the form for document request on Aptina website, but had no response from them.

Another question is about optics for that camera sensor. How do you source it?

regards

Jan

janek@bigpond.net.au:
Another question is about optics for that camera sensor. How do you source it?

regards

Jan

The lenses are purchased from Framos Imaging Solutions.

vjcro

So I have been able to consistently capture JPEG images. There still seems to be a problem with my timing, since some of the images are split inside the frame (eg left half of image on the right side), but otherwise the images look good.

Here is the initialization command straight out of my VB code. Hopefully its clear enough:

'Sensor Core (page 0)

Call RegWrite(“F0”, “0000”) 'change page

Call RegWrite(“05”, “0204”) 'H-blanking (context B)

Call RegWrite(“06”, “0020”) 'V-blanking (B)

Call RegWrite(“09”, “0007”) 'Shutter Width

Call RegWrite(“20”, “0300”) 'Read mode for context B

Call RegWrite(“65”, “2000”) 'Clock control (enable PLL)

Call RegWrite(“66”, “4F07”) 'PLL params

'Color Pipeline (page 1)

Call RegWrite(“F0”, “0001”) 'change page

Call RegWrite(“08”, “01F8”) 'Pipeline control

Call RegWrite(“0B”, “00DF”) 'Enable Internal Clocks

Call RegWrite(“09”, “000A”) 'Disable output bypass (output JPEG)

Call RegWrite(“48”, “0000”) 'Test Pattern

'JPEG + FIFO (page 2)

Call RegWrite(“F0”, “0002”) 'change page (no register changes here)

'Sequencer Variables (ID = 1)

Call RegWrite(“F0”, “0001”) 'change page

Call RegWrite(“C6”, “A120”) '8-bit, offset 0x20: Capture Mode

Call RegWrite(“C8”, “0000”) 'write value

Call RegWrite(“C6”, “A121”) '8-bit, offset 0x21: # of Frames

Call RegWrite(“C8”, “0002”) 'write value

'Mode Variables (ID = 7)

Call RegWrite(“C6”, “2707”) '16-bit, offset 0x07: Frame Width

Call RegWrite(“C8”, “0640”) 'write value (1600)

Call RegWrite(“C6”, “2709”) '16-bit, offset 0x09: Frame Height

Call RegWrite(“C8”, “04B0”) 'write value (1200)

Call RegWrite(“C6”, “270B”) '16-bit, offset 0x0B: JPEG enable

Call RegWrite(“C8”, “0010”) 'write value (enable JPEG in context B)

Call RegWrite(“C6”, “2723”) '16-bit, offset 0x23: extra delay

Call RegWrite(“C8”, “06A1”) 'write value

Call RegWrite(“C6”, “2725”) '16-bit, offset 0x25: row speed

Call RegWrite(“C8”, “0011”) 'write value

Call RegWrite(“C6”, “2772”) '16-bit, offset 0x72: 'JPEG data params (adaptive pxl clock, spoof frames)

Call RegWrite(“C8”, “0267”) 'write value (spoof on)

Call RegWrite(“C6”, “A77E”) '8-bit, offset 0x7E: 'Output Format

Call RegWrite(“C8”, “0000”) 'write value

Call RegWrite(“C6”, “2779”) '16-bit, offset 0x79: 'spoof width

Call RegWrite(“C8”, “0640”) 'write value

Call RegWrite(“C6”, “277B”) '16-bit, offset 0x7B: 'spoof height

Call RegWrite(“C8”, “0258”) 'write value

Call RegWrite(“C6”, “2777”) '16-bit, offset 0x77: 'Len_Timing

Call RegWrite(“C8”, “0606”) 'write value

'JPEG Variables (ID = 9)

Call RegWrite(“C6”, “A906”) '8-bit, offset 0x06: JPEG Format

Call RegWrite(“C8”, “0000”) 'write value

Call RegWrite(“C6”, “A907”) '8-bit, offset 0x07: JPEG settings

Call RegWrite(“C8”, “0014”) 'write value

Call RegWrite(“C6”, “2908”) '16-bit, offset 0x08: restart interval

Call RegWrite(“C8”, “0002”) 'write value

I found out the images came out a lot better when I added a restart interval to correct errors in the JPEG. I can post my header generation code if that would be of interest to you as well, but it is very similar to the C code shown in the developer’s guide. I will also try and post a picture when I can find a site to host it.

Hi Aerospace!

Thanks for the configuration.

But I’m stuck with something pretty basic. Let me ask you: If you set seq.cmd = 2 and then read seq.state, or mode.context, do you get the right value? I tried to configure the camera and when I write something in a register of page 0 or 1, I can read that value back. But the things I write in 0xC6 and 0xC8 doesn’t seem to have any effect. Whatever I set, I get the default values (preview mode, image size 800x600)?!

There is a possibility of HW bug, but could you please tell me is there something I forget in configuration?

Thank you!

vjcro

vcjro,

Yes I’ve been able to read back the values I set in register 0xC8:1. We use this to know when to capture a valid frame. I’m not sure what could be causing your set up to stay at the default value… Are you being sure to change the value in C6 depending on whether your doing an 8-bit or 16-bit read/write?

Also, just out of curiousity, what are you trying to develop this camera for?

Aerospace