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.