Removed locking mechanism for I2C

Develop
Sven Steudte 2017-08-19 04:38:41 +02:00
rodzic f14d1f35ff
commit 851a399db6
6 zmienionych plików z 123 dodań i 220 usunięć

Wyświetl plik

@ -282,7 +282,7 @@ void start_user_modules(void)
chsnprintf(config[5].ssdv_conf.callsign, 7, "DL7AD2"); // SSDV Callsign
config[5].ssdv_conf.ram_buffer = ssdv_buffer; // Camera buffer
config[5].ssdv_conf.ram_size = sizeof(ssdv_buffer); // Buffer size
config[5].ssdv_conf.res = RES_XGA; // Resolution XGA
config[5].ssdv_conf.res = RES_VGA; // Resolution XGA
//config[5].ssdv_conf.redundantTx = true; // Transmit packets twice
start_image_thread(&config[5]);

Wyświetl plik

@ -36,22 +36,22 @@ void BME280_Init(bme280_t *handle, uint8_t address)
handle->address = address;
I2C_read16_LE(address, BME280_REGISTER_DIG_T1, &handle->calib.dig_T1);
I2C_readS16_LE(address, BME280_REGISTER_DIG_T2, &handle->calib.dig_T2);
I2C_readS16_LE(address, BME280_REGISTER_DIG_T3, &handle->calib.dig_T3);
I2C_read16_LE(address, BME280_REGISTER_DIG_T1, (uint16_t*)&handle->calib.dig_T1);
I2C_read16_LE(address, BME280_REGISTER_DIG_T2, (uint16_t*)&handle->calib.dig_T2);
I2C_read16_LE(address, BME280_REGISTER_DIG_T3, (uint16_t*)&handle->calib.dig_T3);
I2C_read16_LE(address, BME280_REGISTER_DIG_P1, &handle->calib.dig_P1);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P2, &handle->calib.dig_P2);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P3, &handle->calib.dig_P3);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P4, &handle->calib.dig_P4);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P5, &handle->calib.dig_P5);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P6, &handle->calib.dig_P6);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P7, &handle->calib.dig_P7);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P8, &handle->calib.dig_P8);
I2C_readS16_LE(address, BME280_REGISTER_DIG_P9, &handle->calib.dig_P9);
I2C_read16_LE(address, BME280_REGISTER_DIG_P1, (uint16_t*)&handle->calib.dig_P1);
I2C_read16_LE(address, BME280_REGISTER_DIG_P2, (uint16_t*)&handle->calib.dig_P2);
I2C_read16_LE(address, BME280_REGISTER_DIG_P3, (uint16_t*)&handle->calib.dig_P3);
I2C_read16_LE(address, BME280_REGISTER_DIG_P4, (uint16_t*)&handle->calib.dig_P4);
I2C_read16_LE(address, BME280_REGISTER_DIG_P5, (uint16_t*)&handle->calib.dig_P5);
I2C_read16_LE(address, BME280_REGISTER_DIG_P6, (uint16_t*)&handle->calib.dig_P6);
I2C_read16_LE(address, BME280_REGISTER_DIG_P7, (uint16_t*)&handle->calib.dig_P7);
I2C_read16_LE(address, BME280_REGISTER_DIG_P8, (uint16_t*)&handle->calib.dig_P8);
I2C_read16_LE(address, BME280_REGISTER_DIG_P9, (uint16_t*)&handle->calib.dig_P9);
I2C_read8(address, BME280_REGISTER_DIG_H1, &handle->calib.dig_H1);
I2C_readS16_LE(address, BME280_REGISTER_DIG_H2, &handle->calib.dig_H2);
I2C_read16_LE(address, BME280_REGISTER_DIG_H2, (uint16_t*)&handle->calib.dig_H2);
I2C_read8(address, BME280_REGISTER_DIG_H3, &handle->calib.dig_H3);
I2C_read8(address, BME280_REGISTER_DIG_H4, &tmp1);

Wyświetl plik

@ -712,64 +712,61 @@ void OV2640_InitGPIO(void)
void OV2640_TransmitConfig(void)
{
// Set to page 1
I2C_write8_locked(OV2640_I2C_ADR, 0xff, 0x01);
I2C_write8_locked(OV2640_I2C_ADR, 0x12, 0x80);
I2C_write8(OV2640_I2C_ADR, 0xff, 0x01);
I2C_write8(OV2640_I2C_ADR, 0x12, 0x80);
chThdSleepMilliseconds(50);
/* Write selected arrays to the camera to initialize it and set the
* desired output format. */
for(uint32_t i=0; (ov2640_init_regs[i].reg != 0xff) || (ov2640_init_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_init_regs[i].reg, ov2640_init_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_init_regs[i].reg, ov2640_init_regs[i].val);
for(uint32_t i=0; (ov2640_size_change_preamble_regs[i].reg != 0xff) || (ov2640_size_change_preamble_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_size_change_preamble_regs[i].reg, ov2640_size_change_preamble_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_size_change_preamble_regs[i].reg, ov2640_size_change_preamble_regs[i].val);
switch(ov2640_conf->res) {
case RES_QCIF:
for(uint32_t i=0; (ov2640_qcif_regs[i].reg != 0xff) || (ov2640_qcif_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_qcif_regs[i].reg, ov2640_qcif_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_qcif_regs[i].reg, ov2640_qcif_regs[i].val);
break;
case RES_QVGA:
for(uint32_t i=0; (ov2640_qvga_regs[i].reg != 0xff) || (ov2640_qvga_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_qvga_regs[i].reg, ov2640_qvga_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_qvga_regs[i].reg, ov2640_qvga_regs[i].val);
break;
case RES_VGA:
for(uint32_t i=0; (ov2640_vga_regs[i].reg != 0xff) || (ov2640_vga_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_vga_regs[i].reg, ov2640_vga_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_vga_regs[i].reg, ov2640_vga_regs[i].val);
break;
case RES_XGA:
for(uint32_t i=0; (ov2640_xga_regs[i].reg != 0xff) || (ov2640_xga_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_xga_regs[i].reg, ov2640_xga_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_xga_regs[i].reg, ov2640_xga_regs[i].val);
break;
case RES_UXGA:
for(uint32_t i=0; (ov2640_uxga_regs[i].reg != 0xff) || (ov2640_uxga_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_uxga_regs[i].reg, ov2640_uxga_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_uxga_regs[i].reg, ov2640_uxga_regs[i].val);
break;
default: // Default QVGA
for(uint32_t i=0; (ov2640_qvga_regs[i].reg != 0xff) || (ov2640_qvga_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_qvga_regs[i].reg, ov2640_qvga_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_qvga_regs[i].reg, ov2640_qvga_regs[i].val);
}
for(uint32_t i=0; (ov2640_format_change_preamble_regs[i].reg != 0xff) || (ov2640_format_change_preamble_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_format_change_preamble_regs[i].reg, ov2640_format_change_preamble_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_format_change_preamble_regs[i].reg, ov2640_format_change_preamble_regs[i].val);
for(uint32_t i=0; (ov2640_yuyv_regs[i].reg != 0xff) || (ov2640_yuyv_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_yuyv_regs[i].reg, ov2640_yuyv_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_yuyv_regs[i].reg, ov2640_yuyv_regs[i].val);
for(uint32_t i=0; (ov2640_jpeg_regs[i].reg != 0xff) || (ov2640_jpeg_regs[i].val != 0xff); i++)
I2C_write8_locked(OV2640_I2C_ADR, ov2640_jpeg_regs[i].reg, ov2640_jpeg_regs[i].val);
I2C_write8(OV2640_I2C_ADR, ov2640_jpeg_regs[i].reg, ov2640_jpeg_regs[i].val);
}
void OV2640_init(ssdv_conf_t *config) {
ov2640_conf = config;
// Take I2C (due to silicon bug of OV2640, it interferes if byte 0x30 transmitted on I2C bus)
I2C_lock();
// Clearing buffer
uint32_t i;
for(i=0; i<ov2640_conf->ram_size; i++)
@ -810,15 +807,10 @@ void OV2640_deinit(void) {
palSetLineMode(LINE_CAM_EN, PAL_MODE_INPUT);
palSetLineMode(LINE_CAM_RESET, PAL_MODE_INPUT);
// Release I2C (due to silicon bug of OV2640, it interferes if byte 0x30 transmitted on I2C bus)
I2C_unlock();
}
bool OV2640_isAvailable(void)
{
I2C_lock();
// Configure pins
OV2640_InitGPIO();
@ -830,14 +822,13 @@ bool OV2640_isAvailable(void)
uint16_t val;
bool ret;
if(I2C_read16_locked(OV2640_I2C_ADR, 0x0A, &val))
if(I2C_read16(OV2640_I2C_ADR, 0x0A, &val))
ret = val == PID_OV2640;
else
ret = false;
palClearLine(LINE_CAM_EN); // Switch off camera
palSetLineMode(LINE_CAM_RESET, PAL_MODE_INPUT); // CAM_RESET
I2C_unlock();
return ret;
}

Wyświetl plik

@ -1,3 +1,8 @@
/*
* Registers by Arducam https://github.com/ArduCAM/Arduino/blob/master/ArduCAM/ov5640_regs.h
* https://github.com/ArduCAM/Arduino/blob/master/ArduCAM/ArduCAM.cpp
*/
#include "ch.h"
#include "hal.h"
#include "ov5640.h"
@ -9,14 +14,11 @@
#define OV5640_I2C_ADR 0x3C
struct regval_list {
uint16_t reg;
uint8_t val;
};
static const struct regval_list OV5640YUV_Sensor_Dvp_Init[] =
{
{ 0x4740, 0x24 },
@ -1025,110 +1027,107 @@ void OV5640_InitGPIO(void)
void OV5640_TransmitConfig(void)
{
chThdSleepMilliseconds(1000);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3103, 0x11);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3008, 0x82);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3103, 0x11);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3008, 0x82);
chThdSleepMilliseconds(100);
for(uint32_t i=0; (OV5640YUV_Sensor_Dvp_Init[i].reg != 0xffff) || (OV5640YUV_Sensor_Dvp_Init[i].val != 0xff); i++)
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, OV5640YUV_Sensor_Dvp_Init[i].reg, OV5640YUV_Sensor_Dvp_Init[i].val);
I2C_write8_16bitreg(OV5640_I2C_ADR, OV5640YUV_Sensor_Dvp_Init[i].reg, OV5640YUV_Sensor_Dvp_Init[i].val);
chThdSleepMilliseconds(500);
for(uint32_t i=0; (OV5640_JPEG_QSXGA[i].reg != 0xffff) || (OV5640_JPEG_QSXGA[i].val != 0xff); i++)
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, OV5640_JPEG_QSXGA[i].reg, OV5640_JPEG_QSXGA[i].val);
I2C_write8_16bitreg(OV5640_I2C_ADR, OV5640_JPEG_QSXGA[i].reg, OV5640_JPEG_QSXGA[i].val);
switch(ov5640_conf->res) {
case RES_QVGA:
for(uint32_t i=0; (OV5640_QSXGA2QVGA[i].reg != 0xffff) || (OV5640_QSXGA2QVGA[i].val != 0xff); i++)
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, OV5640_QSXGA2QVGA[i].reg, OV5640_QSXGA2QVGA[i].val);
I2C_write8_16bitreg(OV5640_I2C_ADR, OV5640_QSXGA2QVGA[i].reg, OV5640_QSXGA2QVGA[i].val);
break;
case RES_VGA:
for(uint32_t i=0; (OV5640_QSXGA2VGA[i].reg != 0xffff) || (OV5640_QSXGA2VGA[i].val != 0xff); i++)
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, OV5640_QSXGA2VGA[i].reg, OV5640_QSXGA2VGA[i].val);
I2C_write8_16bitreg(OV5640_I2C_ADR, OV5640_QSXGA2VGA[i].reg, OV5640_QSXGA2VGA[i].val);
break;
case RES_XGA:
for(uint32_t i=0; (OV5640_QSXGA2XGA[i].reg != 0xffff) || (OV5640_QSXGA2XGA[i].val != 0xff); i++)
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, OV5640_QSXGA2XGA[i].reg, OV5640_QSXGA2XGA[i].val);
I2C_write8_16bitreg(OV5640_I2C_ADR, OV5640_QSXGA2XGA[i].reg, OV5640_QSXGA2XGA[i].val);
break;
case RES_UXGA:
for(uint32_t i=0; (OV5640_QSXGA2UXGA[i].reg != 0xffff) || (OV5640_QSXGA2UXGA[i].val != 0xff); i++)
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, OV5640_QSXGA2UXGA[i].reg, OV5640_QSXGA2UXGA[i].val);
I2C_write8_16bitreg(OV5640_I2C_ADR, OV5640_QSXGA2UXGA[i].reg, OV5640_QSXGA2UXGA[i].val);
break;
default: // Default QVGA
for(uint32_t i=0; (OV5640_QSXGA2QVGA[i].reg != 0xffff) || (OV5640_QSXGA2QVGA[i].val != 0xff); i++)
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, OV5640_QSXGA2QVGA[i].reg, OV5640_QSXGA2QVGA[i].val);
I2C_write8_16bitreg(OV5640_I2C_ADR, OV5640_QSXGA2QVGA[i].reg, OV5640_QSXGA2QVGA[i].val);
}
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x4407, 0x04); // Quantization scale
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x4407, 0x04); // Quantization scale
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3406, 0x00);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3400, 0x04);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3401, 0x00);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3402, 0x04);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3403, 0x00);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3404, 0x04);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3405, 0x00);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0xa3); // lanuch group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5183 ,0x0 );
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3406, 0x00);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3400, 0x04);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3401, 0x00);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3402, 0x04);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3403, 0x00);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3404, 0x04);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3405, 0x00);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0xa3); // lanuch group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5183 ,0x0 );
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5381, 0x1c);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5382, 0x5a);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5383, 0x06);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5384, 0x1a);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5385, 0x66);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5386, 0x80);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5387, 0x82);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5388, 0x80);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5389, 0x02);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x538b, 0x98);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x538a, 0x01);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5381, 0x1c);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5382, 0x5a);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5383, 0x06);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5384, 0x1a);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5385, 0x66);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5386, 0x80);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5387, 0x82);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5388, 0x80);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5389, 0x02);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x538b, 0x98);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x538a, 0x01);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5587, 0x00);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5588, 0x01);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5587, 0x00);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5588, 0x01);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5586, 0x20);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5585, 0x00);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5586, 0x20);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5585, 0x00);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5580, 0x06);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5583, 0x40); // sat U
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5584, 0x10); // sat V
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x5003, 0x08);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x03); // start group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5580, 0x06);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5583, 0x40); // sat U
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5584, 0x10); // sat V
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x5003, 0x08);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0x13); // end group 3
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3212, 0xa3); // launch group
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3a0f, 0x38);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3a10, 0x30);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3a11, 0x61);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3a1b, 0x38);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3a1e, 0x30);
I2C_write8_16bitreg_locked(OV5640_I2C_ADR, 0x3a1f, 0x10);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3a0f, 0x38);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3a10, 0x30);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3a11, 0x61);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3a1b, 0x38);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3a1e, 0x30);
I2C_write8_16bitreg(OV5640_I2C_ADR, 0x3a1f, 0x10);
}
void OV5640_init(ssdv_conf_t *config) {
ov5640_conf = config;
// Take I2C (due to silicon bug of OV5640, it interferes if byte 0x30 transmitted on I2C bus)
I2C_lock();
// Clearing buffer
uint32_t i;
for(i=0; i<ov5640_conf->ram_size; i++)
@ -1169,15 +1168,10 @@ void OV5640_deinit(void) {
palSetLineMode(LINE_CAM_EN, PAL_MODE_INPUT);
palSetLineMode(LINE_CAM_RESET, PAL_MODE_INPUT);
// Release I2C (due to silicon bug of OV5640, it interferes if byte 0x30 transmitted on I2C bus)
I2C_unlock();
}
bool OV5640_isAvailable(void)
{
I2C_lock();
// Configure pins
OV5640_InitGPIO();
@ -1190,7 +1184,7 @@ bool OV5640_isAvailable(void)
uint8_t val, val2;
bool ret;
if(I2C_read8_16bitreg_locked(OV5640_I2C_ADR, 0x300A, &val) && I2C_read8_16bitreg_locked(OV5640_I2C_ADR, 0x300B, &val2)) {
if(I2C_read8_16bitreg(OV5640_I2C_ADR, 0x300A, &val) && I2C_read8_16bitreg(OV5640_I2C_ADR, 0x300B, &val2)) {
ret = val == 0x56 && val2 == 0x40;
} else {
ret = false;
@ -1198,7 +1192,6 @@ bool OV5640_isAvailable(void)
palClearLine(LINE_CAM_EN); // Switch off camera
palSetLineMode(LINE_CAM_RESET, PAL_MODE_INPUT); // CAM_RESET
I2C_unlock();
return ret;
}

Wyświetl plik

@ -6,33 +6,28 @@
#include "hal.h"
#include "pi2c.h"
#define I2C_DRIVER (&I2CD1)
const I2CConfig _i2cfg = {
OPMODE_I2C,
50000,
STD_DUTY_CYCLE,
};
mutex_t pi2c_mtx;
bool i2cSendDriver(I2CDriver *driver, uint8_t addr, uint8_t *txbuf, uint32_t txbytes, uint8_t *rxbuf, uint32_t rxbytes, systime_t timeout) {
static bool I2C_transmit(I2CDriver *driver, uint8_t addr, uint8_t *txbuf, uint32_t txbytes, uint8_t *rxbuf, uint32_t rxbytes, systime_t timeout) {
i2cAcquireBus(driver);
msg_t i2c_status = i2cMasterTransmitTimeout(driver, addr, txbuf, txbytes, rxbuf, rxbytes, timeout);
if(i2c_status == MSG_TIMEOUT) { // Restart I2C at timeout
TRACE_ERROR("I2C > TIMEOUT > RESTART (ADDR 0x%02x)", addr);
i2cStop(driver);
i2cStart(driver, &_i2cfg);
} else if(i2c_status == MSG_RESET && addr != 0x4C) { // Prevent PAC1720 to produce message while it doesnt work below 2.5V
} else if(i2c_status == MSG_RESET) {
TRACE_ERROR("I2C > RESET (ADDR 0x%02x)", addr);
}
i2cReleaseBus(driver);
return i2c_status == MSG_OK;
}
bool I2C_send(uint8_t addr, uint8_t *txbuf, uint32_t txbytes, uint8_t *rxbuf, uint32_t rxbytes, systime_t timeout)
{
return i2cSendDriver(&I2CD1, addr, txbuf, txbytes, rxbuf, rxbytes, timeout);
}
void pi2cInit(void)
{
TRACE_INFO("I2C > Initialize I2C");
@ -41,119 +36,55 @@ void pi2cInit(void)
palSetLineMode(LINE_I2C_SCL, PAL_MODE_ALTERNATE(4) | PAL_STM32_OSPEED_HIGHEST | PAL_STM32_OTYPE_OPENDRAIN); // SCL
i2cStart(&I2CD1, &_i2cfg);
chMtxObjectInit(&pi2c_mtx);
}
// I2C Mutex locked access functions
bool I2C_write8_locked(uint8_t address, uint8_t reg, uint8_t value)
{
uint8_t txbuf[] = {reg, value};
return I2C_send(address, txbuf, 2, NULL, 0, MS2ST(100));
}
bool I2C_write8_16bitreg_locked(uint8_t address, uint16_t reg, uint8_t value) // 16bit register (for OV5640)
{
uint8_t txbuf[] = {reg >> 8, reg & 0xFF, value};
return I2C_send(address, txbuf, 3, NULL, 0, MS2ST(100));
}
bool I2C_writeN_locked(uint8_t address, uint8_t *txbuf, uint32_t length)
{
return I2C_send(address, txbuf, length, NULL, 0, MS2ST(100));
}
bool I2C_read8_locked(uint8_t address, uint8_t reg, uint8_t *val)
{
uint8_t txbuf[] = {reg};
uint8_t rxbuf[1];
bool ret = I2C_send(address, txbuf, 1, rxbuf, 1, MS2ST(100));
*val = rxbuf[0];
return ret;
}
bool I2C_read8_16bitreg_locked(uint8_t address, uint16_t reg, uint8_t *val) // 16bit register (for OV5640)
{
uint8_t txbuf[] = {reg >> 8, reg & 0xFF};
uint8_t rxbuf[1];
bool ret = I2C_send(address, txbuf, 2, rxbuf, 1, MS2ST(100));
*val = rxbuf[0];
return ret;
}
bool I2C_read16_locked(uint8_t address, uint8_t reg, uint16_t *val)
{
uint8_t txbuf[] = {reg};
uint8_t rxbuf[2];
bool ret = I2C_send(address, txbuf, 1, rxbuf, 2, MS2ST(100));
*val = (rxbuf[0] << 8) | rxbuf[1];
return ret;
}
// I2C Mutex unlocked access functions
bool I2C_write8(uint8_t address, uint8_t reg, uint8_t value)
{
I2C_lock();
bool ret = I2C_write8_locked(address, reg, value);
chMtxUnlock(&pi2c_mtx);
return ret;
uint8_t txbuf[] = {reg, value};
return I2C_transmit(I2C_DRIVER, address, txbuf, 2, NULL, 0, MS2ST(100));
}
bool I2C_writeN(uint8_t address, uint8_t *txbuf, uint32_t length)
{
I2C_lock();
bool ret = I2C_writeN_locked(address, txbuf, length);
I2C_unlock();
return ret;
return I2C_transmit(I2C_DRIVER, address, txbuf, length, NULL, 0, MS2ST(100));
}
bool I2C_read8(uint8_t address, uint8_t reg, uint8_t *val)
{
I2C_lock();
bool ret = I2C_read8_locked(address, reg, val);
I2C_unlock();
uint8_t txbuf[] = {reg};
uint8_t rxbuf[1];
bool ret = I2C_transmit(I2C_DRIVER, address, txbuf, 1, rxbuf, 1, MS2ST(100));
*val = rxbuf[0];
return ret;
}
bool I2C_read16(uint8_t address, uint8_t reg, uint16_t *val)
{
I2C_lock();
bool ret = I2C_read16_locked(address, reg, val);
I2C_unlock();
uint8_t txbuf[] = {reg};
uint8_t rxbuf[2];
bool ret = I2C_transmit(I2C_DRIVER, address, txbuf, 1, rxbuf, 2, MS2ST(100));
*val = (rxbuf[0] << 8) | rxbuf[1];
return ret;
}
bool I2C_read16_LE(uint8_t address, uint8_t reg, uint16_t *val) {
bool ret = I2C_read16_locked(address, reg, val);
bool ret = I2C_read16(address, reg, val);
*val = (*val >> 8) | (*val << 8);
return ret;
}
bool I2C_readS16(uint8_t address, uint8_t reg, int16_t *val)
bool I2C_read8_16bitreg(uint8_t address, uint16_t reg, uint8_t *val) // 16bit register (for OV5640)
{
return I2C_read16(address, reg, (uint16_t*)val);
uint8_t txbuf[] = {reg >> 8, reg & 0xFF};
uint8_t rxbuf[1];
bool ret = I2C_transmit(I2C_DRIVER, address, txbuf, 2, rxbuf, 1, MS2ST(100));
*val = rxbuf[0];
return ret;
}
bool I2C_readS16_LE(uint8_t address, uint8_t reg, int16_t* val)
bool I2C_write8_16bitreg(uint8_t address, uint16_t reg, uint8_t value) // 16bit register (for OV5640)
{
return I2C_read16_LE(address, reg, (uint16_t*)val);
}
/**
* Locks all other I2C threads to access I2C
*/
void I2C_lock(void)
{
chMtxLock(&pi2c_mtx);
}
/**
* Unlocks all other I2C threads to access I2C
*/
void I2C_unlock(void)
{
chMtxUnlock(&pi2c_mtx);
uint8_t txbuf[] = {reg >> 8, reg & 0xFF, value};
return I2C_transmit(I2C_DRIVER, address, txbuf, 3, NULL, 0, MS2ST(100));
}

Wyświetl plik

@ -13,27 +13,15 @@
void pi2cInit(void);
// I2C Mutex locked access functions (Access only if I2C has been locked with I2C_lock())
bool I2C_write8_locked(uint8_t address, uint8_t reg, uint8_t value);
bool I2C_writeN_locked(uint8_t address, uint8_t *txbuf, uint32_t length);
bool I2C_read8_locked(uint8_t address, uint8_t reg, uint8_t *val);
bool I2C_read16_locked(uint8_t address, uint8_t reg, uint16_t *val);
bool I2C_write8_16bitreg_locked(uint8_t address, uint16_t reg, uint8_t value); // 16bit register (for OV5640)
bool I2C_read8_16bitreg_locked(uint8_t address, uint16_t reg, uint8_t *val); // 16bit register (for OV5640)
// I2C Mutex unlocked access functions
bool I2C_write8(uint8_t address, uint8_t reg, uint8_t value);
bool I2C_writeN(uint8_t address, uint8_t *txbuf, uint32_t length);
bool I2C_read8(uint8_t address, uint8_t reg, uint8_t *val);
bool I2C_read16(uint8_t address, uint8_t reg, uint16_t *val);
bool I2C_read16_LE(uint8_t address, uint8_t reg, uint16_t *val);
bool I2C_readS16(uint8_t address, uint8_t reg, int16_t *val);
bool I2C_readS16_LE(uint8_t address, uint8_t reg, int16_t* val);
// I2C locking and unlocking
void I2C_lock(void);
void I2C_unlock(void);
bool I2C_write8_16bitreg(uint8_t address, uint16_t reg, uint8_t value); // 16bit register (for OV5640)
bool I2C_read8_16bitreg(uint8_t address, uint16_t reg, uint8_t *val); // 16bit register (for OV5640)
bool I2C_read16_LE(uint8_t address, uint8_t reg, uint16_t *val);
#endif