OV528 Camera Module Library

Revision:
1:06afc809909b
Parent:
0:3f9d7ef7266c
Child:
2:7a563410b23d
--- a/CameraOV528.cpp	Fri Jul 07 16:52:18 2017 +0000
+++ b/CameraOV528.cpp	Fri Jul 07 20:40:26 2017 +0000
@@ -104,6 +104,7 @@
     _read_buf_head = 0;
     _read_buf_tail = 0;
     _read_wake_pos = READ_WAKE_POS_INVALID;
+    this->log_func = debug;
 }
 
 CameraOV528::~CameraOV528()
@@ -111,10 +112,21 @@
     powerdown();
 }
 
-void CameraOV528::powerup()
+void CameraOV528::attach_debug_function(void (*func)(const char* fmt, ...))
+{
+    this->log_func = func;
+}
+
+int CameraOV528::camera_error(const char* message)
+{
+    log_func("%s\r\n",message);
+    return -1;
+}
+
+int CameraOV528::powerup()
 {
     if (_init_done) {
-        return;
+        return 0;
     }
 
     _serial.attach(this, &CameraOV528::_rx_irq, SerialBase::RxIrq);
@@ -130,7 +142,7 @@
     }
 
     if (!success) {
-        error("Unable to communicate with camera");
+        return camera_error("Unable to communicate with camera");
     }
 
     // Acknowledge the SYNC read in _init_sequence with an ACK
@@ -143,22 +155,23 @@
     _set_package_size(picture_buffer_size_limit);
 
     _init_done = false;
+    return 0;
 }
 
-void CameraOV528::powerup(uint32_t baud)
+int CameraOV528::powerup(uint32_t baud)
 {
     _baud = baud;
-    powerup();
+    return powerup();
 }
 
-void CameraOV528::powerdown()
+int CameraOV528::powerdown()
 {
     if (!_init_done) {
-        return;
+        return 0;
     }
 
     if (!_send_cmd(POWER_DOWN, 0)) {
-        error("Powerdown failed");
+        return camera_error("Powerdown failed");
     }
 
     // Reset picture transfer variables
@@ -174,9 +187,10 @@
     _flush_rx();
 
     _init_done = false;
+    return 0;
 }
 
-void CameraOV528::take_picture(void)
+int CameraOV528::take_picture(void)
 {
     // Ensure driver is powered up
     powerup();
@@ -191,29 +205,30 @@
     // Take snapshot
     camera_printf("Taking snapshot\r\n");
     if (!_send_cmd(SNAPSHOT, 0)) {
-        error("Take snapshot failed");
+        return camera_error("Take snapshot failed");
     }
 
     // Start picture transfer
     camera_printf("Starting transfer\r\n");
     const GetSetting request = GET_JPEG_PREVIEW_PICTURE;
     if (!_send_cmd(GET_PICTURE, request)) {
-        error("Get picture command failed");
+        return camera_error("Get picture command failed");
     }
     camera_command_t resp = {0};
     uint32_t size_read = _read((uint8_t*)&resp, COMMAND_LENGTH, 1000);
     if (size_read != COMMAND_LENGTH) {
-        error("Get picture response invalid");
+        return camera_error("Get picture response invalid");
     }
-    if (resp.header != 0xAA)  error("Get picture response invalid sync");
-    if (resp.command != DATA)  error("Get picture response invalid data");
-    if (resp.param[0] != request)  error("Get picture response invalid content");
+    if (resp.header != 0xAA)  camera_error("Get picture response invalid sync");
+    if (resp.command != DATA)  camera_error("Get picture response invalid data");
+    if (resp.param[0] != request)  camera_error("Get picture response invalid content");
     picture_length = (resp.param[1] << 0) |
              (resp.param[2] << 8) |
              (resp.param[3] << 16);
     picture_data_id = 0;
     uint32_t payload_length = picture_buffer_size_limit - PIC_PAYLOAD_OVERHEAD;
     picture_data_id_count = divide_round_up(picture_length, payload_length);
+    return 0;
 }
 
 uint32_t CameraOV528::get_picture_size()
@@ -260,7 +275,7 @@
     }
 
     if (!valid_resolution) {
-        error("Invalid resolution");
+        camera_error("Invalid resolution");
     }
 
     _resolution = resolution;
@@ -279,7 +294,7 @@
     }
 
     if (!valid_format) {
-        error("Invalid format");
+        camera_error("Invalid format");
     }
 
     _format = format;
@@ -293,7 +308,7 @@
     // Assert no rounding errors
     MBED_ASSERT(PIC_CLOCK_HZ / ( 2 * (div2 + 1) ) / ( 2 * (div1 + 1)) == _baud);
     if (!_send_cmd(SET_BAUD_RATE, div1, div2)) {
-        error("_set_baud failed");
+        camera_error("_set_baud failed");
     }
     _serial.baud(_baud);
 }
@@ -304,23 +319,23 @@
     uint8_t size_low = (size >> 0) & 0xff;
     uint8_t size_high = (size >> 8) & 0xff;
     if (!_send_cmd(SET_PACKAGE_SIZE, 0x08, size_low, size_high, 0)) {
-        error("_set_package_size failed");
+        camera_error("_set_package_size failed");
     }
 }
 
 void CameraOV528::_set_fmt_and_res(Format fmt, Resolution res)
 {
     if (!_send_cmd(INITIAL, 0x00, _format, 0x00, _resolution)) {
-        error("_set_fmt_and_res failed");
+        camera_error("_set_fmt_and_res failed");
     }
 }
 
-void CameraOV528::_read_picture_block()
+int CameraOV528::_read_picture_block()
 {
     const uint32_t payload_length = picture_buffer_size_limit - PIC_PAYLOAD_OVERHEAD;
     if (picture_data_id >= picture_data_id_count) {
         // Transfer complete
-        return;
+        return 0;
     }
 
     // Send an ACK to indicate that the next block id should be sent
@@ -334,7 +349,7 @@
     uint32_t size_to_read = min(size_left, payload_length) + PIC_PAYLOAD_OVERHEAD;
     uint32_t size_read = _read(picture_buffer, size_to_read);
     if (size_read != size_to_read) {
-        error("Image data protocol error");
+        return camera_error("Image data protocol error");
     }
 
     // Validate checksum
@@ -343,7 +358,7 @@
         checksum += picture_buffer[i];
     }
     if (picture_buffer[size_read - 2] != checksum) {
-        error("Image data checksum failure");
+        return camera_error("Image data checksum failure");
     }
 
     // Update buffer information
@@ -361,6 +376,7 @@
                   picture_length - payload_length * picture_data_id +
                   PIC_PAYLOAD_OVERHEAD - size_read);
     picture_data_id++;
+    return 0;
 }
 
 void CameraOV528::_send_ack(uint8_t p1, uint8_t p2, uint8_t p3, uint8_t p4)
@@ -381,7 +397,7 @@
 
         // Check for overflow
         if (_read_buf_head + 1 == _read_buf_tail) {
-            error("RX buffer overflow");
+            camera_error("RX buffer overflow");
         }
 
         // Add data