SmartWheels self-driving race car. Designed for NXP Cup. Uses FRDM-KL25Z, area-scan camera, and simple image processing to detect and navigate any NXP spec track.

Dependencies:   TSI USBDevice mbed-dev

Fork of SmartWheels by haofan Zheng

Hardwares/Camera.cpp

Committer:
hazheng
Date:
2017-02-21
Revision:
26:5814404856e2
Parent:
25:6f63053cee81
Child:
27:c68f711e5b67

File content as of revision 26:5814404856e2:

#include "Camera.h"

#include "Core.h"
#include "OV7725RegAddr.h"
#include "PinAssignment.h"
#include "SWUSBServer.h"

namespace
{
    DigitalOut testLED(LED_GREEN, 1);
    
    bool isInLine = false;
    uint8_t currentCol = 0;
    uint8_t outCurrentCol = 0;
    
    uint16_t currentRow = 0;
    uint16_t outCurrentRow = 0;
}


static void OnPixelClock()
{
    if(isInLine)
    {
        ++currentCol;
    }
}

static void OnHorizontalRise()
{
    isInLine = true;
    
    ++currentRow;
}

static void OnHorizontalFall()
{
    isInLine = false;
    
    outCurrentCol = currentCol;
    currentCol = 0;
}

static void OnFrameClock()
{
    outCurrentRow = currentRow;
    currentRow = 0;
    testLED = testLED.read() == 1 ? 0 : 1;
}

Camera::Camera(SW::Core & core) : 
    m_core(core),
    m_pClock(InterruptIn(PIN_CC_PCLOCK)),
    m_href(InterruptIn(PIN_CC_HREF)),
    m_vsnyc(InterruptIn(PIN_CC_VSYNC)),
    m_hasPic(false),
    m_regBuf(NULL),
    m_debugOutputTimer(0.0f)
{
    m_regBuf = new OV7725RegBuf(m_core);

#if (CAMERA_PIXEL_WIDTH == 80)
    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x14);
#elif (CAMERA_PIXEL_WIDTH == 160)
    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x28);
#elif (CAMERA_PIXEL_WIDTH == 240)
    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x3c);
#elif (CAMERA_PIXEL_WIDTH == 320)
    m_regBuf->SCCBWrite(OV7725_HOutSize, 0x50);
#endif

#if (CAMERA_PIXEL_HEIGHT == 60 )
    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x1E);
#elif (CAMERA_PIXEL_HEIGHT == 120 )
    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x3c);
#elif (CAMERA_PIXEL_HEIGHT == 180 )
    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x5a);
#elif (CAMERA_PIXEL_HEIGHT == 240 )
    m_regBuf->SCCBWrite(OV7725_VOutSize, 0x78);
#endif
    
    m_regBuf->SCCBWrite(OV7725_COM4,  0x01);
    m_regBuf->SCCBWrite(OV7725_CLKRC, 0x86);
    
    char buf[20];
    unsigned char tempV = m_regBuf->SCCBRead(OV7725_HOutSize);
    sprintf(buf, "CamReg %#x=%#x", OV7725_HOutSize, tempV);
    m_core.GetUSBServer().PushReliableMsg('D', buf);
    
    tempV = m_regBuf->SCCBRead(OV7725_VOutSize);
    sprintf(buf, "CamReg %#x=%#x", OV7725_VOutSize, tempV);
    m_core.GetUSBServer().PushReliableMsg('D', buf);
    
    tempV = m_regBuf->SCCBRead(OV7725_COM4);
    sprintf(buf, "CamReg %#x=%#x", OV7725_COM4, tempV);
    m_core.GetUSBServer().PushReliableMsg('D', buf);
    
    tempV = m_regBuf->SCCBRead(OV7725_CLKRC);
    sprintf(buf, "CamReg %#x=%#x", OV7725_CLKRC, tempV);
    m_core.GetUSBServer().PushReliableMsg('D', buf);
    
    delete m_regBuf;
    m_regBuf = NULL;
    
    StartReceivingPic();
}

Camera::~Camera()
{
    
}

void Camera::Update(float deltaTime)
{
    m_debugOutputTimer += deltaTime;
    
    if(m_debugOutputTimer >= 2.0)
    {
        char buf[20];
        sprintf(buf, "ColSize: %u", outCurrentCol);
        m_core.GetUSBServer().PushUnreliableMsg('D', buf);
        sprintf(buf, "RowSize: %u", outCurrentRow);
        m_core.GetUSBServer().PushUnreliableMsg('D', buf);
        
        m_debugOutputTimer = 0.0f;
    }
    
}

void Camera::StartReceivingPic()
{
    m_pClock.rise(&OnPixelClock);
    m_href.rise(&OnHorizontalRise);
    m_href.fall(&OnHorizontalFall);
    m_vsnyc.fall(&OnFrameClock);
}

void Camera::StopReceivingPic()
{
    m_vsnyc.fall(NULL);
    m_href.fall(NULL);
    m_href.rise(NULL);
    m_pClock.rise(NULL);
}

bool Camera::HasPicture() const
{
    return m_hasPic;
}

const unsigned char * Camera::GetPicture() const
{
    return NULL; //m_pics[m_currentIndex == 0 ? 1 : 0];
}