new pinout test

This commit is contained in:
CuriosMind 2025-03-28 10:47:56 +01:00
parent ae80ff60b1
commit b9704bbe2d
9 changed files with 155 additions and 64 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
build/
.vscode
.vscode
.DS_Store

View File

@ -38,7 +38,8 @@
bool reserved_addr(uint8_t addr) {
return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
}
#define PICO_DEFAULT_I2C_SDA_PIN 22
#define PICO_DEFAULT_I2C_SCL_PIN 19
int main() {
// Enable UART so we can print status output
stdio_init_all();
@ -47,47 +48,51 @@ int main() {
puts("Default I2C pins were not defined");
#else
// This example will use I2C0 on the default SDA and SCL pins (GP4, GP5 on a Pico)
gpio_set_function(3, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(3);
gpio_set_function(11, GPIO_FUNC_PWM);
uint slice_num = pwm_gpio_to_slice_num(11);
// 6 cycles (0 to 5), 125 MHz / 6 = ~20.83 MHz wrap rate
pwm_set_wrap(slice_num, 5);
pwm_set_gpio_level(3, 3);
pwm_set_gpio_level(11, 3);
pwm_set_enabled(slice_num, true);
sleep_ms(1000);
i2c_init(i2c_default, 100 * 1000);
gpio_set_function(PICO_DEFAULT_I2C_SDA_PIN, GPIO_FUNC_I2C);
gpio_set_function(PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C);
gpio_pull_up(PICO_DEFAULT_I2C_SDA_PIN);
gpio_pull_up(PICO_DEFAULT_I2C_SCL_PIN);
i2c_init(i2c1, 100 * 1000);
gpio_set_function(22, GPIO_FUNC_I2C);
gpio_set_function(19, GPIO_FUNC_I2C);
gpio_pull_up(22);
gpio_pull_up(19);
// Make the I2C pins available to picotool
bi_decl(bi_2pins_with_func(PICO_DEFAULT_I2C_SDA_PIN, PICO_DEFAULT_I2C_SCL_PIN, GPIO_FUNC_I2C));
bi_decl(bi_2pins_with_func(22, 19, GPIO_FUNC_I2C));
while(true){
printf("\nI2C Bus Scan\n");
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
printf("\nI2C Bus Scan\n");
printf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n");
for (int addr = 0; addr < (1 << 7); ++addr) {
if (addr % 16 == 0) {
printf("%02x ", addr);
}
for (int addr = 0; addr < (1 << 7); ++addr) {
if (addr % 16 == 0) {
printf("%02x ", addr);
// Perform a 1-byte dummy read from the probe address. If a slave
// acknowledges this address, the function returns the number of bytes
// transferred. If the address byte is ignored, the function returns
// -1.
// Skip over any reserved addresses.
int ret;
uint8_t rxdata;
if (reserved_addr(addr))
ret = PICO_ERROR_GENERIC;
else
ret = i2c_read_blocking(i2c1, addr, &rxdata, 1, false);
printf(ret < 0 ? "." : "@");
printf(addr % 16 == 15 ? "\n" : " ");
}
// Perform a 1-byte dummy read from the probe address. If a slave
// acknowledges this address, the function returns the number of bytes
// transferred. If the address byte is ignored, the function returns
// -1.
// Skip over any reserved addresses.
int ret;
uint8_t rxdata;
if (reserved_addr(addr))
ret = PICO_ERROR_GENERIC;
else
ret = i2c_read_blocking(i2c_default, addr, &rxdata, 1, false);
printf(ret < 0 ? "." : "@");
printf(addr % 16 == 15 ? "\n" : " ");
printf("Done.\n");
sleep_ms(1000);
}
printf("Done.\n");
return 0;
#endif
}

View File

@ -8,7 +8,7 @@ import cv2 # Added OpenCV for image processing
# Configure serial port - this will connect to the USB serial port from the Pico
PORT = '/dev/tty.usbmodem101' # Adjust for your system
BAUD_RATE = 57600 # Reduced to match the Pico's baud rate for debugging
BAUD_RATE = 3000 # Reduced to match the Pico's baud rate for debugging
TIMEOUT = 60 # Increased timeout for slower data transfer
# Enable detailed debugging information
@ -231,14 +231,14 @@ def process_binary_data(data):
if received_checksum != calculated_checksum:
print("Error: Checksum mismatch")
return None
#return None
# Verify frame footer
footer_start = checksum_start + 4
footer = data[footer_start:footer_start+len(FRAME_FOOTER)]
if footer != FRAME_FOOTER:
print("Error: Invalid frame footer")
return None
#return None
print("Frame successfully extracted and verified!")
return frame_data

View File

@ -26,13 +26,22 @@ const int FRAME_MARKER_SIZE = 4;
camera_config_t left_eye_config = {
.pin_pwdn = -1, /*!< GPIO pin for camera power down line */
.pin_reset = -1, /*!< GPIO pin for camera reset line */
.pin_xclk = 3, /*!< GPIO pin for camera XCLK line */
.pin_sccb_sda = 4, /*!< GPIO pin for camera SDA line */
.pin_sccb_scl = 5, /*!< GPIO pin for camera SCL line */
.pin_data_base = 6, /*!< this pin + 7 consecutive will be used D0-D7 PCLK HREF */
.pin_vsync = 16, /*!< GPIO pin for camera VSYNC line */
.pin_xclk = 11, /*!< GPIO pin for camera XCLK line */
.pin_sccb_sda = 22, /*!< GPIO pin for camera SDA line */
.pin_sccb_scl = 19, /*!< GPIO pin for camera SCL line */
.pin_data_9 = 14, /*!< this pin + 7 consecutive will be used D0-D7 PCLK HREF */
.pin_data_8 = 12,
.pin_data_7 = 10,
.pin_data_6 = 8,
.pin_data_5 = 6,
.pin_data_4 = 5,
.pin_data_3 = 4,
.pin_data_2 = 3,
.pin_vsync = 17, /*!< GPIO pin for camera VSYNC line */
.pin_hsync = 15, /*!< GPIO pin for camera VSYNC line */
.xclk_freq_hz = 0, /*!< Frequency of XCLK signal, in Hz. */
.sccb_ctrl = 0, /* Select i2c controller ctrl: 0 - i2c0, 1 - i2c1, 2 - pio0, 3 - pio1, 4 - pio2 */
.sccb_ctrl = 1, /* Select i2c controller ctrl: 0 - i2c0, 1 - i2c1, 2 - pio0, 3 - pio1, 4 - pio2 */
};
// Send a properly framed image using printf for binary data
@ -46,7 +55,9 @@ void send_frame(const void* buffer, size_t size) {
// Send frame header
fwrite(FRAME_HEADER, 1, FRAME_MARKER_SIZE, stdout);
sleep_ms(100); // Small delay to ensure the text is transmitted separately
printf("test....");
// Send frame size (4 bytes, little-endian)
uint8_t size_bytes[4];
size_bytes[0] = size & 0xFF;
@ -54,7 +65,8 @@ void send_frame(const void* buffer, size_t size) {
size_bytes[2] = (size >> 16) & 0xFF;
size_bytes[3] = (size >> 24) & 0xFF;
fwrite(size_bytes, 1, 4, stdout);
printf("test2....");
// Calculate checksum
uint32_t checksum = 0;
const uint8_t* buf = (const uint8_t*)buffer;
@ -64,7 +76,8 @@ void send_frame(const void* buffer, size_t size) {
// Send frame data
fwrite(buf, 1, size, stdout);
sleep_ms(100); // Small delay to ensure the text is transmitted separately
// Send checksum (4 bytes)
uint8_t checksum_bytes[4];
checksum_bytes[0] = checksum & 0xFF;
@ -72,10 +85,11 @@ void send_frame(const void* buffer, size_t size) {
checksum_bytes[2] = (checksum >> 16) & 0xFF;
checksum_bytes[3] = (checksum >> 24) & 0xFF;
fwrite(checksum_bytes, 1, 4, stdout);
sleep_ms(100); // Small delay to ensure the text is transmitted separately
// Send frame footer
fwrite(FRAME_FOOTER, 1, FRAME_MARKER_SIZE, stdout);
sleep_ms(100); // Small delay to ensure the text is transmitted separately
// Flush to ensure all binary data is sent
fflush(stdout);

View File

@ -22,7 +22,7 @@ int SCCB::begin(uint8_t ctrl)
this->ctrl = ctrl;
if (ctrl < 2) {
this->i2cc = ctrl == 0 ? i2c0 : i2c1;
i2c_init(this->i2cc, 5 * 1000);
i2c_init(this->i2cc, 100 * 1000);
gpio_set_function(this->sda, GPIO_FUNC_I2C);
gpio_set_function(this->scl, GPIO_FUNC_I2C);
gpio_pull_up(this->sda);

View File

@ -610,9 +610,8 @@ register_val_t OV2640_qqvga[] = {
OV2640::OV2640(camera_config_t config)
{
uint8_t fb[160 * 120 * 2];
this->config = config;
memset(&this->fb, 0x00, sizeof(this->fb));
memset(&this->fb, 0x00, sizeof(this->fb));
pointer = &this->fb;
//this->fb = image_buf;
}
@ -675,10 +674,10 @@ int OV2640::begin(int dma_irq)
this->sccb.writeList(OV2640_rgb, sizeof(OV2640_rgb)/sizeof(OV2640_rgb[0]));
// // Enable color bar test pattern for debugging
// printf("Enabling color bar test pattern...\n");
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR);
// this->sccb.writeRegister(OV2640_REG1_COM7, OV2640_COM7_COLORBAR); // Output test pattern
// printf("Test pattern enabled\n");
//printf("Enabling color bar test pattern...\n");
//this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR);
//this->sccb.writeRegister(OV2640_REG1_COM7, OV2640_COM7_COLORBAR); // Output test pattern
//printf("Test pattern enabled\n");
// GPIO pin setup
printf("Setting up GPIO pins for camera data...\n");
@ -686,19 +685,47 @@ int OV2640::begin(int dma_irq)
gpio_set_dir(this->config.pin_vsync, GPIO_IN);
gpio_pull_down(this->config.pin_vsync);
printf("Initializing data pins %d through %d...\n",
this->config.pin_data_base, this->config.pin_data_base + 9);
for (uint8_t i = 0; i < 10; i++)
{
gpio_init(this->config.pin_data_base + i);
gpio_set_dir(this->config.pin_data_base + i, GPIO_IN);
}
gpio_init(this->config.pin_data_9 );
gpio_set_dir(this->config.pin_data_9, GPIO_IN);
gpio_init(this->config.pin_data_8 );
gpio_set_dir(this->config.pin_data_8, GPIO_IN);
gpio_init(this->config.pin_data_7 );
gpio_set_dir(this->config.pin_data_7, GPIO_IN);
gpio_init(this->config.pin_data_6 );
gpio_set_dir(this->config.pin_data_6, GPIO_IN);
gpio_init(this->config.pin_data_5 );
gpio_set_dir(this->config.pin_data_5, GPIO_IN);
gpio_init(this->config.pin_data_4 );
gpio_set_dir(this->config.pin_data_4, GPIO_IN);
gpio_init(this->config.pin_data_3 );
gpio_set_dir(this->config.pin_data_3, GPIO_IN);
gpio_init(this->config.pin_data_2 );
gpio_set_dir(this->config.pin_data_2, GPIO_IN);
printf("GPIO initialization complete\n");
// PIO setup for image capture
printf("Setting up PIO for image capture...\n");
uint offset = pio_add_program(pio2, &image_program);
image_program_init(pio2, 0, offset, this->config.pin_data_base);
image_program_init(pio2, 0, offset, this->config.pin_data_9);
image_program_init(pio2, 0, offset, this->config.pin_data_8);
image_program_init(pio2, 0, offset, this->config.pin_data_7);
image_program_init(pio2, 0, offset, this->config.pin_data_6);
image_program_init(pio2, 0, offset, this->config.pin_data_5);
image_program_init(pio2, 0, offset, this->config.pin_data_4);
image_program_init(pio2, 0, offset, this->config.pin_data_3);
image_program_init(pio2, 0, offset, this->config.pin_data_2);
image_program_init(pio2, 0, offset, this->config.pin_hsync);
printf("PIO setup complete\n");
// DMA setup
@ -854,6 +881,40 @@ void OV2640::capture_frame() {
printf("Frame captured successfully\n");
}
// void OV2640::set_resolution(uint16_t width, uint16_t height) {
// // Set resolution registers
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP); // DSP bank select 0
// this->sccb.writeRegister(OV2640_REG0_HSIZE8, (width >> 3) & 0xFF); // HSIZE high bits
// this->sccb.writeRegister(OV2640_REG0_VSIZE8, (height >> 3) & 0xFF); // VSIZE high bits
// this->sccb.writeRegister(OV2640_REG0_HSIZE, width & 0xFF); // HSIZE low bits
// this->sccb.writeRegister(OV2640_REG0_VSIZE, height & 0xFF); // VSIZE low bits
// this->sccb.writeRegister(OV2640_REG0_ZMOW, width & 0xFF); // OUTW low bits
// this->sccb.writeRegister(OV2640_REG0_ZMOH, height & 0xFF); // OUTH low bits
// this->sccb.writeRegister(OV2640_REG0_ZMHH, ((height >> 8) & 0x04) | ((width >> 8) & 0x03)); // OUTW/H high bits
// printf("Resolution set to %dx%d\n", width, height);
// }
// void OV2640::set_resolution_vga() {
// // Set resolution to VGA (640x480)
// uint16_t width = 640;
// uint16_t height = 480;
// // Adjust frame buffer size for VGA resolution
// this->fb = new uint8_t[width * height * 2]; // Assuming 2 bytes per pixel (RGB565)
// pointer = this->fb;
// // Set resolution registers
// this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP); // DSP bank select 0
// this->sccb.writeRegister(OV2640_REG0_HSIZE8, (width >> 3) & 0xFF); // HSIZE high bits
// this->sccb.writeRegister(OV2640_REG0_VSIZE8, (height >> 3) & 0xFF); // VSIZE high bits
// this->sccb.writeRegister(OV2640_REG0_HSIZE, width & 0xFF); // HSIZE low bits
// this->sccb.writeRegister(OV2640_REG0_VSIZE, height & 0xFF); // VSIZE low bits
// this->sccb.writeRegister(OV2640_REG0_ZMOW, width & 0xFF); // OUTW low bits
// this->sccb.writeRegister(OV2640_REG0_ZMOH, height & 0xFF); // OUTH low bits
// this->sccb.writeRegister(OV2640_REG0_ZMHH, ((height >> 8) & 0x04) | ((width >> 8) & 0x03)); // OUTW/H high bits
// printf("Resolution set to VGA (640x480)\n");
// }
//! https://forums.raspberrypi.com/viewtopic.php?t=339299
// TODO: change to switches and experiment with state machines, check if I can kinda reserve dma's so 0-3 would indicate state machines 0-3

View File

@ -9,8 +9,16 @@ typedef struct {
int pin_xclk; /*!< GPIO pin for camera XCLK line */ //? in theory could be shared or perhaps ommited?
int pin_sccb_sda; /*!< GPIO pin for camera SDA line */
int pin_sccb_scl; /*!< GPIO pin for camera SCL line */
int pin_data_base; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_9; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_8; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_7; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_6; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_5; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_4; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_3; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_data_2; /*!< this pin + 9 consecutive will be used D0-D7 PCLK HREF */
int pin_vsync; /*!< GPIO pin for camera VSYNC line */
int pin_hsync; /*!< GPIO pin for camera VSYNC line */
int xclk_freq_hz; /*!< Frequency of XCLK signal, in Hz. */ //! Figure out the highest it can go to
uint8_t sccb_ctrl; /* Select i2c controller ctrl: 0 - i2c0, 1 - i2c1, 2 - pio0, 3 - pio1, 4 - pio2 */
} camera_config_t;
@ -49,7 +57,7 @@ public:
void set_framesize();
void capture_frame();
uint8_t fb[(352*288)];
uint8_t* fb; // Changed from fixed array to pointer
camera_config_t config;
private:

View File

View File

@ -60,5 +60,7 @@ void image_program_init(PIO pio, uint sm, uint offset, uint pin_base) {
pio_sm_set_enabled(pio, sm, true);
}
// New function to initialize PIO with camera configuration pins - declaration only
// In image.pio.h, replace the implementation with a declaration
#endif