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
Diff: Hardwares/ArduCAM.cpp
- Revision:
- 34:f79db3bc2f86
- Parent:
- 33:e3fcc4d6bb9b
- Child:
- 35:ac4fcca21560
diff -r e3fcc4d6bb9b -r f79db3bc2f86 Hardwares/ArduCAM.cpp --- a/Hardwares/ArduCAM.cpp Fri Mar 03 18:26:44 2017 +0000 +++ b/Hardwares/ArduCAM.cpp Thu Mar 09 19:21:50 2017 +0000 @@ -17,35 +17,52 @@ DigitalOut testLED2(LED_RED, 1); -/* -inline static uint8_t ardu_cam_spi_io(int address, int value = 0x00) + +inline void ardu_cam_spi_write_8(int address, int value) { - //g_spi_port.lock(); - + // 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 | 0x80); + g_spi_port.write(value); + // take the SS pin high to de-select the chip: + cam_cs = 1; +} + +inline uint8_t ardu_cam_spi_read_8(int address) +{ + // take the SS pin low to select the chip: cam_cs = 0; - g_spi_port.write(address); - uint8_t result = g_spi_port.write(value); + // send in the address and value via SPI: + g_spi_port.write(address & 0x7F); + uint8_t value = static_cast<uint8_t>(g_spi_port.write(0x00)); + // take the SS pin high to de-select the chip: cam_cs = 1; + return value; +} +/* +inline void ardu_cam_spi_set_burst() +{ + cam_cs = 0; + + g_spi_port.write(BURST_FIFO_READ & 0x7F); - //g_spi_port.unlock(); + cam_cs = 1; +} + +inline uint16_t ardu_cam_spi_burst_read_16() +{ + cam_cs = 0; - return result; + uint16_t value = static_cast<uint16_t>(g_spi_port.write(0x00)); + value = (value << 8) & 0xFF00; + value = value | static_cast<uint16_t>(g_spi_port.write(0x00)); + + cam_cs = 1; + return value; } */ -//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() { @@ -62,7 +79,7 @@ camReg->SCCBWrite(0xff, 0x01); camReg->SCCBWrite(0x12, 0x80); wait_ms(5); - camReg->WriteRegSet(OV2640Prog::QQVGA); + camReg->WriteRegSet(OV2640Prog::QVGA); wait_ms(100); camReg->SCCBWrite(0xff, 0x01); @@ -85,15 +102,15 @@ - uint8_t VerNum = ardu_cam_read_reg(0x40); - VerNum = ardu_cam_read_reg(0x40); + uint8_t VerNum = ardu_cam_spi_read_8(0x40); + VerNum = ardu_cam_spi_read_8(0x40); 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); + ardu_cam_spi_write_8(ARDUCHIP_TEST1, ARDUCHIP_TEST_MSG); + uint8_t testV = ardu_cam_spi_read_8(ARDUCHIP_TEST1); if(VerNum != 0x61 || testV != ARDUCHIP_TEST_MSG) { g_core.GetUSBServer().PushReliableMsg('D', "CameraInit Fa"); @@ -125,95 +142,53 @@ switch(mode) { case MCU2LCD_MODE: - ardu_cam_write_reg(ARDUCHIP_MODE, MCU2LCD_MODE); + ardu_cam_spi_write_8(ARDUCHIP_MODE, MCU2LCD_MODE); break; case CAM2LCD_MODE: - ardu_cam_write_reg(ARDUCHIP_MODE, CAM2LCD_MODE); + ardu_cam_spi_write_8(ARDUCHIP_MODE, CAM2LCD_MODE); break; //case LCD2MCU_MODE: - //ardu_cam_write_reg(ARDUCHIP_MODE, LCD2MCU_MODE); + //ardu_cam_spi_write_8(ARDUCHIP_MODE, LCD2MCU_MODE); //break; default: - ardu_cam_write_reg(ARDUCHIP_MODE, CAM2LCD_MODE); + ardu_cam_spi_write_8(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, 0x00); - ardu_cam_write_reg(ARDUCHIP_FIFO, FIFO_START_MASK); + ardu_cam_spi_write_8(ARDUCHIP_FIFO, FIFO_CLEAR_MASK); + ardu_cam_spi_write_8(ARDUCHIP_CAP_CTRL, 0x00); + ardu_cam_spi_write_8(ARDUCHIP_FIFO, FIFO_START_MASK); } uint32_t ardu_cam_get_fifo_length() { uint32_t len1,len2,len3,length=0; - len1 = ardu_cam_read_reg(FIFO_SIZE1); - len2 = ardu_cam_read_reg(FIFO_SIZE2); - len3 = ardu_cam_read_reg(FIFO_SIZE3) & 0x07; + len1 = ardu_cam_spi_read_8(FIFO_SIZE1); + len2 = ardu_cam_spi_read_8(FIFO_SIZE2); + len3 = ardu_cam_spi_read_8(FIFO_SIZE3) & 0x07; length = ((len3 << 16) | (len2 << 8) | len1) & 0x07ffff; return length; } -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; -} - uint8_t ardu_cam_get_pixel() { - uint16_t VH = ardu_cam_read_reg(SINGLE_FIFO_READ); - uint16_t VL = ardu_cam_read_reg(SINGLE_FIFO_READ); - - //char buf[20]; - //sprintf(buf, "h%#x", VH); - //g_core.GetUSBServer().PushReliableMsg('D', buf); - //sprintf(buf, "l%#x", VL); - //g_core.GetUSBServer().PushReliableMsg('D', buf); + uint16_t VH = ardu_cam_spi_read_8(SINGLE_FIFO_READ); + uint16_t VL = ardu_cam_spi_read_8(SINGLE_FIFO_READ); + //uint16_t VL = ardu_cam_spi_burst_read_16(); VL = (VL & 0x00FF) | ((VH << 8) & 0xFF00); uint8_t ch = ((VL & 0xF800) >> 9);// << 2; float pixel = (static_cast<float>(ch) * 0.21); - //sprintf(buf, "c%#x", ch); - //g_core.GetUSBServer().PushReliableMsg('D', buf); - ch = ((VL & 0x07E0) >> 3);// << 2; pixel += (static_cast<float>(ch) * 0.72); - //sprintf(buf, "c%#x", ch); - //g_core.GetUSBServer().PushReliableMsg('D', buf); - ch = (VL & 0x001F) << 2; pixel += (static_cast<float>(ch) * 0.07); - //sprintf(buf, "c%#x", ch); - //g_core.GetUSBServer().PushReliableMsg('D', buf); - //sprintf(buf, "p%#x", static_cast<uint8_t>(pixel)); - //g_core.GetUSBServer().PushReliableMsg('D', buf); - return static_cast<uint8_t>(pixel); } @@ -231,6 +206,7 @@ std::string lineBuf; lineBuf.resize(RESOLUTION_WIDTH + 1); + //ardu_cam_spi_set_burst(); ardu_cam_get_pixel(); //Get the first dummy pixel for (uint8_t i = 0; i < RESOLUTION_HEIGHT; ++i) @@ -244,7 +220,7 @@ } g_core.GetUSBServer().PushReliableMsg('P', lineBuf); - wait(0.4); + wait(0.40); } } \ No newline at end of file