Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 9 of 9

Thread: SPI TFT + OV7670 camera project on teensy 4

  1. #1
    Junior Member
    Join Date
    Jun 2020
    Posts
    10

    SPI TFT + OV7670 camera project on teensy 4

    Hello,

    I am working on a project with both a 320*240 SPI touch screen and an OV7670 camera.

    Using the arduino libraries, I can make things work...
    BUT, the imx seems to have HW assist for both SPI and CCIR656 compatible cameras. Is there any library or anything available to use the HW assist to DMA the screen data out in a (semi) continuous way (so that I can tell the HW: send new framebuffer, and have it being sent using DMA or something like this in parallel with the rest of my processing.
    Simillary, I need/want to aquire the camera data in a HW way without having to do it in FW and get an interrupt/message/flag set once a new frame is available.

    Thanks,
    Cyrille

  2. #2
    I've not messed with CurtE's lib ILI9341_t3n, but i believe it has a way to use DMA to get crazy fast updates. Have a look at the demosauce example that comes with the ILI9341_t3n lib. It shows very fast screens updates. @bitbank also did some lib optimizations that get high performance.

    some more info here
    https://forum.pjrc.com/threads/31719...70-camera-chip


    If you do get vid working, would you mind sharing some example code? I've been wanting to get a camera working as well, but have not had the time to tinker.

  3. #3
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,954
    You did not say which 320x240 display, nor which Teensy... but assuming you have a teensy with enough memory (t3.5/3.6, T4, T4.1)

    As mentioned, for my ili9341_t3n library (https://github.com/KurtE/ILI9341_t3n) has DMA support.
    Also our ST7735_t3/ST7789 library also has the same support, This is included with Teensyduino.

    With these you can say: tft.useFrameBuffer(true);
    And all writes you do go to the screen buffer.

    You can do a direct update of the screen from frame buffer without using DMA by: tft.updateScreen();

    You can use DMA by doing tft.updateScreenAsync();
    And later test for the update completed or wait for the completion.

    If you are using a processor with enough memory (T4.x) you can setup to do a sort of double buffer. There is a real basic example of this that I recently added to the ILI9341_t3n library, which sets the frame buffer to one buffer, starts the DMA operation, then tell system to use 2nd buffer and updates it and waits for the first DMA to complete before restarting the DMA operation, which starts from the 2nd buffer, which you then switch back to first...

    Note: the above is not continuous. You can also setup to do continuous updates tft.updateScreenAsync(true);
    which will continuously update screen. Note: you do run into issues where you are updating the memory potentially at same time as the DMA is writing out to screen... So can get partial updates if your code is not careful. You do have options to get an interrupt function called as each frame completes and also the ability on the half frame, such that you can setup your code to update the half the screen you know that part of the screen is not updating. I think there is an example showing that as well.

    Also I earlier mentioned in another thread, it would probably be possible to do a combination of the two, where the DMA chain could contain two frames, so you know which frame is active and update the other... But so far I have not done this as no one sounded like they had a usage need for it.

  4. #4
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Hello,

    Thanks a lot for the info. I will definitely go that route. I will most likely use the updateScreen version as I will not write at anytime in the screen.

    I am using a Teensy 4.0 and a ILI9341 screen. Sorry, I should have specified it at the start!

    Cyrille

  5. #5
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Hello,

    After some issues with my board (teensy4.0) (I fired it I guess and had to replace it)... I am back in business trying to implement my project, but I am having issues.

    I am trying to use one of the demo programs to test it... but it does not work with the ILI9341_t3n library.
    It does however work with the Adafruit_ILI9341.h library.

    Here is the beginning of my code for reference.

    Thanks for your help,
    Cyrille


    #define TFT_CS 10 // TFT CS pin is connected to arduino pin 8
    #define TFT_RST 8 // TFT RST pin is connected to arduino pin 9
    #define TFT_DC 9 // TFT DC pin is connected to arduino pin 10
    // initialize ILI9341 TFT library

    #if 1
    #include "ILI9341_t3n.h"
    ILI9341_t3n tft = ILI9341_t3n(TFT_CS, TFT_DC, TFT_RST);
    #else
    #include <Adafruit_GFX.h>
    #include <Adafruit_ILI9341.h>
    Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
    #endif

    void setup() {
    Serial.begin(9600);
    Serial.println("ILI9341 Test!");

    tft.begin();

    pinMode(14, OUTPUT); analogWrite(14, 200); // LED backlight...

    // read diagnostics (optional but can help debug problems)
    uint8_t x = tft.readcommand8(ILI9341_RDMODE);
    Serial.print("Display Power Mode: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDMADCTL);
    Serial.print("MADCTL Mode: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDPIXFMT);
    Serial.print("Pixel Format: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDIMGFMT);
    Serial.print("Image Format: 0x"); Serial.println(x, HEX);
    x = tft.readcommand8(ILI9341_RDSELFDIAG);
    Serial.print("Self Diagnostic: 0x"); Serial.println(x, HEX);

    Serial.println(F("Benchmark Time (microseconds)"));

    Serial.print(F("Screen fill "));
    Serial.println(testFillScreen());
    delay(500);
    Last edited by cyrille; 07-02-2020 at 12:25 PM. Reason: update

  6. #6
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,954
    Sorry, it is unclear to me, what the issue is?
    but it does not work with the ILI9341_t3n library.
    Does not give me enough information to give any suggestions.

    Does not compile? If so what are the compile errors.
    Screen is blank?
    Garbage on the screen?

    It simply does not print out the registers?

  7. #7
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Hello,

    Yes, sorry, I should have been more descriptive, I apologize.
    Blank screen is what I am getting...

    But, the good news is that I seem to have found the issue. SPI Clock speed. I dropped it to 20000000 from 30Mhz and it now seems to work...

    My next step is to try to turn on framebuffer and async SPI sending... but I am betting blocked there also.
    I added this after the tft.begin();
    tft.useFrameBuffer(true);
    tft.updateScreenAsync(true);

    But this does not seem to work. I end up with what seems like a blank screen with every other line slightly darker.
    I hope that this is enough description to figure out what is wrong.
    I wish I could tell more, but I don't know what information is relevant there.
    I tried reducing the clock rate, but it did not help.

    edit: removing the call to tft.updateScreenAsync(true); and adding calls to tft.updateScreen(); tft.updateScreenAsync(false); or on a regular basis does however work.
    So the library is drawing on the framebuffer, but the continious async update does not seem to work.

    Cyrille
    Last edited by cyrille; 07-02-2020 at 01:45 PM.

  8. #8
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,118
    Quote Originally Posted by cyrille View Post
    I dropped it to 20000000 from 30Mhz and it now seems to work...
    Any chance you can share the photo or a link to the specific ILI9341 display you're using?

    Most of them work up to 30 MHz and much faster. Would be really helpful to know which models out there need to run slower.

  9. #9
    Junior Member
    Join Date
    Jun 2020
    Posts
    10
    Hello,

    No problem, it is a module that I got from aliexpress:
    https://fr.aliexpress.com/item/33040...4d836c37psGsuk

    Could the speed issue be due to the long connectors that I am using? VS a direct connection or a connection through a shield?

    I was able to make some more progresses.
    I can get it to work with tft.updateScreenAsync(true); BUT, I had to move the call a little bit lower in my code.
    As if I needed to start performing some operation, or as if they was some timing/delay needed before I could call it.

    Also, in the demo, the first part of the demo (what is in the setup call) did work. But the code in the "loop" function did not.
    I found that by commenting out tft.setRotation(rotation); it was back to working. This seems as if a call to tft.setRotation is not compatible with async update. Am I missing something? I will be trying to stop the update annd wait for completion, change the rotation and turn it back on to test...

    Click image for larger version. 

Name:	IMG_1824.jpg 
Views:	5 
Size:	111.3 KB 
ID:	20837

    Cyrille
    Last edited by cyrille; 07-02-2020 at 03:08 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •