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-08
Revision:
13:7dcb1642ef99
Parent:
9:b72e18f80f49
Child:
25:6f63053cee81

File content as of revision 13:7dcb1642ef99:

#include "Camera.h"

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


DigitalOut testLED(LED_BLUE, 1);

void Camera::OnPixelClock()
{
    /*
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[0].read();
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[1].read();
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[2].read();
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[3].read();
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[4].read();
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[5].read();
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[6].read();
    m_pics[m_currentIndex][(m_currentRow * CAM_MAX_COL) + m_currentCol++] = 0;//m_dIn[7].read();
    */
}

void Camera::OnHorizontalClock()
{
    m_currentRow++;
    m_currentCol = 0;
}

void Camera::OnFrameClock()
{
    m_currentIndex = m_currentIndex == 0 ? 1 : 0;
    m_currentRow = 0;
    m_currentCol = 0;
    m_hasPic = true;
    
    testLED = testLED.read() == 1 ? 0 : 1;
}

Camera::Camera(SW::Core & core) : 
    m_core(core),
    m_pClock(InterruptIn(PTD7)),
    m_href(InterruptIn(PTD6)),
    m_vsnyc(InterruptIn(PTA17)),
    m_sccbCtrl(I2C(PIN_CC_SDA, PIN_CC_SCL)),
    m_currentIndex(0),
    m_currentRow(0),
    m_currentCol(0),
    m_hasPic(false)
{
    /*
    m_dIn.push_back(DigitalIn(PTE5));
    m_dIn.push_back(DigitalIn(PTE4));
    m_dIn.push_back(DigitalIn(PTE3));
    m_dIn.push_back(DigitalIn(PTE2));
    m_dIn.push_back(DigitalIn(PTB11));
    m_dIn.push_back(DigitalIn(PTB10));
    m_dIn.push_back(DigitalIn(PTB9));
    m_dIn.push_back(DigitalIn(PTB8));
    */
    //m_pClock.fall(callback(this, &Camera::OnPixelClock));
    //m_href.rise(callback(this, &Camera::OnHorizontalClock));
    //m_vsnyc.rise(callback(this, &Camera::OnFrameClock));
    
}

Camera::~Camera()
{
    
}

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

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

//Blocking method. Do not use during the running state!!
void Camera::SCCBWrite(uint8_t RegAddr, uint8_t Data)
{
    m_sccbCtrl.start();
    m_sccbCtrl.write(OV7725_WRITE);
    wait_us(OV7725_WRITEWAIT);
    m_sccbCtrl.write(RegAddr);
    wait_us(OV7725_WRITEWAIT);
    m_sccbCtrl.write(Data);
    m_sccbCtrl.stop();
}

//Blocking method. Do not use during the running state!!
uint8_t Camera::SCCBRead(const uint8_t RegAddr)
{      
    m_sccbCtrl.start();
    m_sccbCtrl.write(OV7725_WRITE);
    wait_us(OV7725_WRITEWAIT);
    m_sccbCtrl.write(RegAddr);
    m_sccbCtrl.stop();
    wait_us(OV7725_WRITEWAIT);    
 
    m_sccbCtrl.start();
    m_sccbCtrl.write(OV7725_READ);
    wait_us(OV7725_WRITEWAIT);
    char readValue = m_sccbCtrl.read(OV7725_NOACK);
    m_sccbCtrl.stop();
    
    return readValue;
}

//Blocking method. Do not use during the running state!!
void Camera::ReadRegisters()
{
    
    m_sccbCtrl.lock();
    m_sccbCtrl.frequency(100000);
    for(int i = 0; i < OV7725_LAST_ADDR + 1; ++i)
    {
        if(!OV7725RegBuf::IsAddressReserved(i))
        {
            char buf[10];
            sprintf(buf, "%#x-%#x", i, SCCBRead(i));
            m_core.GetUSBServer().PushUnreliableMsg('D', buf);
            
            wait(0.1);
        }
    }
    m_sccbCtrl.unlock();
}