Re: Någon som har hållit på med DCMI förut?
Postat: 15 april 2022, 09:30:37
Svenskt forum för elektroniksnack.
https://elektronikforumet.com/forum/
Kod: Markera allt
uint8_t addr = 0;
uint8_t errors = 0;
uint8_t busys = 0;
uint8_t timeouts = 0;
for(uint8_t i = 0; i < 128; i++){
HAL_StatusTypeDef status = HAL_I2C_IsDeviceReady(&hi2c1, i, 5, 100);
if(status == HAL_ERROR){
errors++;
}else if(status == HAL_BUSY){
busys++;
}else if(status == HAL_TIMEOUT){
timeouts++;
}else if(status == HAL_OK){
addr = i;
break;
}
}
Kod: Markera allt
ErrorStatus camera_write_register(uint8_t address, uint8_t value){
// Create start condition on SCCB/I2C interface
SCCB_start();
// Write data (Address of slave device for Write) on SCCB/I2C interface
if(SCCB_write(WriteAddress) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Write data (Address of register in Camera Module)on SCCB/I2C interface
HAL_Delay(1);
if(SCCB_write(address) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Write data (Data to write into register in Camera Module)on SCCB/I2C interface
if(SCCB_write(value) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Create stop condition on SCCB/I2C interface
SCCB_stop();
return SUCCESS;
}
Kod: Markera allt
typedef enum{
SUCCESS = 0U,
ERROR = !SUCCESS
} ErrorStatus;
Kod: Markera allt
static void SCCB_start(){
// Configure SCCB_D of SCCB/I2C interface as output for write
SCCB_D_dir(OUT);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
}
Kod: Markera allt
static ErrorStatus SCCB_write(uint8_t data){
uint8_t status;
// Configure SCCB_D of SCCB/I2C interface as output for write
SCCB_D_dir(OUT);
// Write data bit by bit on SCCB/I2C
for(uint8_t i = 0; i < 8; i++) {
if((data & 0x80) == 0x80) // If bit in Data is high, write high on SCCB/I2C
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_SET);
else // If bit in Data is low, write low on SCCB/I2C
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_RESET);
data <<= 1; // Rotate Data for write next bit
// Create clock pulse on SCCB/I2C
// ___ On SIO_C pin (SCCB clock)
// \___
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
}
// Read acknowladge from Camera Module to confirm received data
HAL_Delay(1);
// Configure SCCB_D of SCCB/I2C interface as input for read
SCCB_D_dir(IN);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
// If acknowladge is OK return SUCCESS else if is incorrect return ERROR
if(!HAL_GPIO_ReadPin(SCCB_D_GPIO_Port, SCCB_D_Pin))
status = ERROR;
else
status = SUCCESS;
// Pulse on SCCB/I2C fall down from high
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
// Configure SCCB_D of SCCB/I2C interface back to output for write
SCCB_D_dir(OUT);
return status;
}
Kod: Markera allt
static void SCCB_D_dir(Direction Dir){
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = SCCB_D_Pin;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Mode = Dir == IN ? GPIO_MODE_INPUT : GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(SCCB_D_GPIO_Port, &GPIO_InitStructure);
}
Kod: Markera allt
if((data & 0x80) == 0x80) // If bit in Data is high, write high on SCCB/I2C
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_SET);
else // If bit in Data is low, write low on SCCB/I2C
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_RESET);
data <<= 1; // Rotate Data for write next bit
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
Kod: Markera allt
SCCB_D_dir(IN);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
// If acknowladge is OK return SUCCESS else if is incorrect return ERROR
if(!HAL_GPIO_ReadPin(SCCB_D_GPIO_Port, SCCB_D_Pin))
status = ERROR;
else
status = SUCCESS;
// Pulse on SCCB/I2C fall down from high
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
// Configure SCCB_D of SCCB/I2C interface back to output for write
SCCB_D_dir(OUT);
Kod: Markera allt
/**
* @brief Change configuration I/O pin SCCB_D as OUT/IN
* @param Configure SCCB_D pin as IN/OUT
* @arg IN = 1, OUT = 0
* @retval None
*/
static void SCCB_D_dir(Direction Dir){
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = SCCB_D_Pin;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Mode = Dir == IN ? GPIO_MODE_INPUT : GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(SCCB_D_GPIO_Port, &GPIO_InitStructure);
}
/**
* @brief Read data form SCCB/I2C interface
* @param None
* @retval Data: received data from SCCB/I2C interface
*/
static uint8_t SCCB_read(){
// Write to Data zero for correct return data
uint8_t data = 0;
// Configure SCCB_D of SCCB/I2C interface as input for read
SCCB_D_dir(IN);
// Delay for SCCB/I2C interface
HAL_Delay(1);
// Read data from SCCBI/I2C interface
for(uint8_t i = 8; i > 0; i--) {
// Delay for SCCB/I2C
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
// Shift data << 1
data = data << 1;
// Read SCCB_D pin value
if(HAL_GPIO_ReadPin(SCCB_D_GPIO_Port, SCCB_D_Pin))
data = data + 1;
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
}
// Return received data from SCCBI/I2C interface
return data;
}
/**
* @brief Write data on SCCB/I2C interface
* @param Data: data for write on SCCBI/I2C interface
* @retval status
*/
static ErrorStatus SCCB_write(uint8_t data){
uint8_t status;
// Configure SCCB_D of SCCB/I2C interface as output for write
SCCB_D_dir(OUT);
// Write data bit by bit on SCCB/I2C
for(uint8_t i = 0; i < 8; i++) {
if((data & 0x80) == 0x80) // If bit in Data is high, write high on SCCB/I2C
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_SET);
else // If bit in Data is low, write low on SCCB/I2C
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_RESET);
data <<= 1; // Rotate Data for write next bit
// Create clock pulse on SCCB/I2C
// ___ ___ __On SIO_C pin (SCCB clock)
// \___/ \__/ \__
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
}
// Read acknowladge from Camera Module to confirm received data
HAL_Delay(1);
// Configure SCCB_D of SCCB/I2C interface as input for read
SCCB_D_dir(IN);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
// If acknowladge is OK return SUCCESS else if is incorrect return ERROR
if(!HAL_GPIO_ReadPin(SCCB_D_GPIO_Port, SCCB_D_Pin))
status = ERROR;
else
status = SUCCESS;
// Pulse on SCCB/I2C fall down from high
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
// Configure SCCB_D of SCCB/I2C interface back to output for write
SCCB_D_dir(OUT);
return status;
}
/**
* @brief Create on SCCB/I2C interface "START" condition of transmission
* |-> Start
* ___|
* SCCB_D \______
* ______
* SIO_C \___
* @param None
* @retval None
*/
static void SCCB_start(){
// Configure SCCB_D of SCCB/I2C interface as output for write
SCCB_D_dir(OUT);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
}
/**
* @brief Create on SCCB/I2C interface "STOP" condition of transmission
* |-> Stop
* | __
* SCCB_D ______/ \__
* ________
* SIO_C ___/
* @param None
* @retval None
*/
static void SCCB_stop(){
// Configure SCCB_D of SCCB/I2C interface as output for write
SCCB_D_dir(OUT);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_SET);
HAL_Delay(1);
}
/**
* @brief Create on SCCB/I2C interface "NoACK"
* _____
* SCCB_D \___
* ___
* SIO_C \_____
* @param None
* @retval None
*/
static void no_ack(){
// Configure SCCB_D of SCCB/I2C interface as output for write
SCCB_D_dir(OUT);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_C_GPIO_Port, SCCB_C_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
HAL_GPIO_WritePin(SCCB_D_GPIO_Port, SCCB_D_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
}
void camera_reset(){
camera_write_register(OV7670_COM7, 0x80);
}
ErrorStatus camera_write_register(uint8_t address, uint8_t value){
// Create start condition on SCCB/I2C interface
SCCB_start();
// Write data (Address of slave device for Write) on SCCB/I2C interface
if(SCCB_write(WriteAddress) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Write data (Address of register in Camera Module)on SCCB/I2C interface
HAL_Delay(1);
if(SCCB_write(address) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Write data (Data to write into register in Camera Module)on SCCB/I2C interface
if(SCCB_write(value) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Create stop condition on SCCB/I2C interface
SCCB_stop();
return SUCCESS;
}
ErrorStatus camera_read_register(uint8_t address, uint8_t *data){
// Create start condition on SCCB/I2C interface
SCCB_start();
// Write data (Address of slave device for Write) on SCCB/I2C interface
if(SCCB_write(WriteAddress) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Write data (Address of register in Camera Module)on SCCB/I2C interface
HAL_Delay(1);
if(SCCB_write(address) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
// Create stop condition on SCCB/I2C interface
SCCB_stop();
// Delay for SCCB/I2C
HAL_Delay(1);
// Create start condition on SCCB/I2C interface
SCCB_start();
// Write data (Address of slave device for Read) on SCCB/I2C interface
if(SCCB_write(ReadAddress) == ERROR){
SCCB_stop(); // Create stop condition on SCCB/I2C interface
return ERROR;
}
HAL_Delay(1);
// Received data from Camera Module (SCCB/I2C)
*data = SCCB_read();
// No acknowlage on SCCB/I2C interface
no_ack();
// Create stop condition on SCCB/I2C interface
SCCB_stop();
// Return data
return SUCCESS;
}
Varför anses det vara ovanligt?JimmyAndersson skrev: ↑6 maj 2022, 00:04:00 Edit: Kamera med i2c: Jag har inte stött på någon tyvärr.
JimmyAndersson skrev: ↑6 maj 2022, 23:47:53 Stopp en sekund nu…
Ovanligt? Det har jag inte skrivit.
Kolla konversationen:
Daniel: Någon som vet en DCMI kamera med I2C?
Jimmy: Jag har inte stött på någon tyvärr.
Daniel: Varför anses det vara ovanligt?
Hur gick det där till?
(Sen ser jag att du har fastnat lite vid ordet ”bitbanga”.)
Hmm… Det finns ju kameror med ethernet. Axis (svenskt jättetrevligt företag) kameror brukar ha utmärkt dokumentation dessutom. Men då är det kompletta kameror, typ övervakning/konsert.
Men personligen hade jag tyckt det var kuligast med DCMI.
Gillar det formatet av någon anledning. Men å andra sidan.. vad vet jag.. Jag gillar ju även assembler.![]()