kopia lustrzana https://github.com/DL7AD/pecanpico9
Removed locking mechanism for I2C
rodzic
f14d1f35ff
commit
851a399db6
|
@ -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]);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue