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/ArduCAM.cpp

Committer:
hazheng
Date:
2017-03-01
Revision:
29:f87d8790f57d
Parent:
28:271fc8445e89
Child:
32:5badeff825dc

File content as of revision 29:f87d8790f57d:

#include "ArduCAM.h"

#include "GlobalVariable.h"
#include "SWUSBServer.h"

extern SPI g_spi_port;

DigitalOut cam_cs(PIN_ACC_CS);

DigitalOut testLED2(LED_RED, 1);

/*
inline static uint8_t ardu_cam_spi_io(int address, int value = 0x00)
{
    //g_spi_port.lock();
    
    cam_cs = 0;
    g_spi_port.write(address);
    uint8_t result = g_spi_port.write(value);
    cam_cs = 1;
    
    //g_spi_port.unlock();
    
    return result;
}
*/

//Write ArduChip internal registers
void ardu_cam_write_reg(uint8_t addr, uint8_t data)
{
    ardu_cam_bus_write(addr | 0x80, data);
}
 
//Read ArduChip internal registers
uint8_t ardu_cam_read_reg(uint8_t addr)
{
    uint8_t data;
    data = ardu_cam_bus_read(addr & 0x7F);
    return data;
}

bool ardu_cam_init()
{
    uint8_t VerNum = ardu_cam_read_reg(0x40);
    VerNum = ardu_cam_read_reg(0x40);
    
    char buf[20];
    sprintf(buf, "Ardu Ver %#x", VerNum);
    g_core.GetUSBServer().PushReliableMsg('D', buf);
    
    ardu_cam_write_reg(ARDUCHIP_TEST1, ARDUCHIP_TEST_MSG);
    uint8_t testV = ardu_cam_read_reg(ARDUCHIP_TEST1);
    if(VerNum != 0x61 || testV != ARDUCHIP_TEST_MSG)
    {
        g_core.GetUSBServer().PushReliableMsg('D', "CameraInit Fa");
        return false;
    }
    g_core.GetUSBServer().PushReliableMsg('D', "CameraInit Su");
    
    ardu_cam_set_mode(MCU2LCD_MODE);
    ardu_cam_start_capture();
    
    wait(0.1);
    ardu_cam_set_mode(CAM2LCD_MODE);
    
    
    unsigned char tempV = ardu_cam_read_reg(ARDUCHIP_MODE);
    sprintf(buf, "Ardu Stat %#x", tempV);
    g_core.GetUSBServer().PushReliableMsg('D', buf);
    
    tempV = ardu_cam_read_reg(ARDUCHIP_CAP_CTRL);
    sprintf(buf, "Ardu FS1 %#x", tempV);
    g_core.GetUSBServer().PushReliableMsg('D', buf);
    
    return true;
}

void ardu_cam_set_mode(uint8_t mode)
{
    //ardu_cam_bus_io(ARDUCHIP_MODE, mode);
    switch(mode)
    {
        case MCU2LCD_MODE:
            ardu_cam_write_reg(ARDUCHIP_MODE, MCU2LCD_MODE);
            break;
        case CAM2LCD_MODE:
            ardu_cam_write_reg(ARDUCHIP_MODE, CAM2LCD_MODE);
            break;
        //case LCD2MCU_MODE:
            //ardu_cam_write_reg(ARDUCHIP_MODE, LCD2MCU_MODE);
            //break;
        default:
            ardu_cam_write_reg(ARDUCHIP_MODE, CAM2LCD_MODE);
            break;
    }
}

void ardu_cam_start_capture()
{
    ardu_cam_write_reg(ARDUCHIP_FIFO, FIFO_CLEAR_MASK);
    ardu_cam_write_reg(ARDUCHIP_CAP_CTRL, 0x05);
    ardu_cam_write_reg(ARDUCHIP_FIFO, FIFO_START_MASK);
}

int ardu_cam_bus_write(int address, int value)
{
    // take the SS pin low to select the chip:
    cam_cs = 0;
    //  send in the address and value via SPI:
    g_spi_port.write(address);
    g_spi_port.write(value);
    // take the SS pin high to de-select the chip:
    cam_cs = 1;
    
    return value;
}
 
uint8_t ardu_cam_bus_read(int address)
{ 
    uint8_t value = 0;
    // take the SS pin low to select the chip:
    cam_cs = 0;
    //  send in the address and value via SPI:
    g_spi_port.write(address);
    value = g_spi_port.write(0x00);
    // take the SS pin high to de-select the chip:
    cam_cs = 1;
    return value;
}