Fix compilation issues
mmm yes debugging with printf
This commit is contained in:
parent
76bf0c144e
commit
c36531c679
@ -35,7 +35,8 @@ pico_sdk_init()
|
||||
|
||||
# Add executable. Default name is the project name, version 0.1
|
||||
|
||||
add_executable(PicoIris src/PicoIris.cpp )
|
||||
add_executable(PicoIris src/PicoIris.cpp src/ov2640/camera.cpp src/ov2640/SCCB.cpp src/pio/i2c/pio_i2c.c)
|
||||
#add_executable(PicoIris bus_scan.c)
|
||||
|
||||
pico_set_program_name(PicoIris "PicoIris")
|
||||
pico_set_program_version(PicoIris "0.1")
|
||||
@ -47,22 +48,21 @@ pico_generate_pio_header(PicoIris ${CMAKE_CURRENT_LIST_DIR}/src/pio/i2c/i2c.pio)
|
||||
pico_enable_stdio_uart(PicoIris 0)
|
||||
pico_enable_stdio_usb(PicoIris 1)
|
||||
|
||||
# Add the standard library to the build
|
||||
target_link_libraries(PicoIris
|
||||
pico_stdlib)
|
||||
|
||||
# Add the standard include files to the build
|
||||
target_include_directories(PicoIris PRIVATE
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
src/
|
||||
src/ov2640/
|
||||
src/pio/i2c/
|
||||
)
|
||||
|
||||
# Add any user requested libraries
|
||||
target_link_libraries(PicoIris
|
||||
pico_stdlib
|
||||
hardware_spi
|
||||
hardware_i2c
|
||||
hardware_dma
|
||||
hardware_pwm
|
||||
hardware_pio
|
||||
hardware_interp
|
||||
hardware_timer
|
||||
|
||||
93
bus_scan.c
Normal file
93
bus_scan.c
Normal file
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
// Sweep through all 7-bit I2C addresses, to see if any slaves are present on
|
||||
// the I2C bus. Print out a table that looks like this:
|
||||
//
|
||||
// I2C Bus Scan
|
||||
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
||||
// 00 . . . . . . . . . . . . . . . .
|
||||
// 10 . . @ . . . . . . . . . . . . .
|
||||
// 20 . . . . . . . . . . . . . . . .
|
||||
// 30 . . . . @ . . . . . . . . . . .
|
||||
// 40 . . . . . . . . . . . . . . . .
|
||||
// 50 . . . . . . . . . . . . . . . .
|
||||
// 60 . . . . . . . . . . . . . . . .
|
||||
// 70 . . . . . . . . . . . . . . . .
|
||||
// E.g. if addresses 0x12 and 0x34 were acknowledged.
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
#include "pico/binary_info.h"
|
||||
#include "hardware/i2c.h"
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/spi.h"
|
||||
#include "hardware/i2c.h"
|
||||
#include "hardware/dma.h"
|
||||
#include "hardware/pio.h"
|
||||
#include "hardware/interp.h"
|
||||
#include "hardware/timer.h"
|
||||
#include "hardware/pwm.h"
|
||||
#include "hardware/clocks.h"
|
||||
#include "hardware/uart.h"
|
||||
// I2C reserves some addresses for special purposes. We exclude these from the scan.
|
||||
// These are any addresses of the form 000 0xxx or 111 1xxx
|
||||
bool reserved_addr(uint8_t addr) {
|
||||
return (addr & 0x78) == 0 || (addr & 0x78) == 0x78;
|
||||
}
|
||||
|
||||
int main() {
|
||||
// Enable UART so we can print status output
|
||||
stdio_init_all();
|
||||
#if !defined(i2c_default) || !defined(PICO_DEFAULT_I2C_SDA_PIN) || !defined(PICO_DEFAULT_I2C_SCL_PIN)
|
||||
#warning i2c/bus_scan example requires a board with I2C pins
|
||||
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);
|
||||
// 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_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);
|
||||
// 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));
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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");
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
@ -18,13 +18,13 @@
|
||||
camera_config_t left_eye_config = {
|
||||
.pin_pwdn = -1, /*!< GPIO pin for camera power down line */ //? Also called PWDN, or set to -1 and tie to GND
|
||||
.pin_reset = -1, /*!< GPIO pin for camera reset line */ //? Cam reset, or set to -1 and tie to 3.3V
|
||||
.pin_xclk = 0, /*!< GPIO pin for camera XCLK line */ //? in theory could be shared or perhaps ommited?
|
||||
.pin_sccb_sda = 0, /*!< GPIO pin for camera SDA line */
|
||||
.pin_sccb_scl = 0, /*!< GPIO pin for camera SCL line */
|
||||
.pin_data_base = 0, /*!< this pin + 7 consecutive will be used D0-D7 */
|
||||
.pin_vsync = 0, /*!< GPIO pin for camera VSYNC line */
|
||||
.pin_href = 0, /*!< GPIO pin for camera HREF line */
|
||||
.pin_pclk = 0, /*!< GPIO pin for camera PCLK line */
|
||||
.pin_xclk = 3, /*!< GPIO pin for camera XCLK line */ //? in theory could be shared or perhaps ommited?
|
||||
.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 */
|
||||
.pin_vsync = 16, /*!< GPIO pin for camera VSYNC line */
|
||||
.pin_href = 15, /*!< GPIO pin for camera HREF line */
|
||||
.pin_pclk = 14, /*!< GPIO pin for camera PCLK line */
|
||||
.xclk_freq_hz = 0, /*!< Frequency of XCLK signal, in Hz. */ //! Figure out the highest it can go to
|
||||
.sccb_ctrl = 0, /* Select i2c controller ctrl: 0 - i2c0, 1 - i2c1, 2 - pio0, 3 - pio1, 4 - pio2 */
|
||||
};
|
||||
@ -33,11 +33,18 @@ int main()
|
||||
{
|
||||
stdio_init_all();
|
||||
|
||||
sleep_ms(4000);
|
||||
printf("Hello World!");
|
||||
|
||||
printf("construct OV2640!");
|
||||
OV2640 left_cam = OV2640(left_eye_config);
|
||||
printf("begin OV2640!");
|
||||
left_cam.begin(DMA_IRQ_0);
|
||||
|
||||
|
||||
while (true) {
|
||||
printf("Hello, world!\n");
|
||||
sleep_ms(1000);
|
||||
//printf("Hello, world!\n");
|
||||
//sleep_ms(1000);
|
||||
tight_loop_contents();
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,8 +59,8 @@ int SCCB::readRegister(uint8_t reg)
|
||||
i2c_write_blocking(this->i2cc, OV2640_ADDR, ®, 1, true); // TODO: check if true or false is correct here
|
||||
i2c_read_blocking(this->i2cc, OV2640_ADDR, buf, 1, false); // false - finished with bus
|
||||
}else {
|
||||
pio_i2c_write_blocking(this->pio, this->sm, OV2640_ADDR, ®, 1);
|
||||
pio_i2c_read_blocking(this->pio, this->sm, OV2640_ADDR, buf, 1);
|
||||
//pio_i2c_write_blocking(this->pio, this->sm, OV2640_ADDR, ®, 1);
|
||||
//pio_i2c_read_blocking(this->pio, this->sm, OV2640_ADDR, buf, 1);
|
||||
}
|
||||
return buf[0];
|
||||
}
|
||||
@ -74,7 +74,7 @@ void SCCB::writeRegister(uint8_t reg, uint8_t value)
|
||||
if (this->ctrl < 2) {
|
||||
i2c_write_blocking(this->i2cc, OV2640_ADDR, buf, 2, false);
|
||||
}else {
|
||||
pio_i2c_write_blocking(this->pio, this->sm, OV2640_ADDR, buf, 2);
|
||||
//pio_i2c_write_blocking(this->pio, this->sm, OV2640_ADDR, buf, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,6 +84,6 @@ void SCCB::writeList(const register_val_t *cfg,
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
writeRegister(cfg[i].reg, cfg[i].value);
|
||||
sleep_ms(1000); // Some cams require, else lockup on init
|
||||
sleep_ms(10); // Some cams require, else lockup on init
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,8 @@
|
||||
#include <cstdint>
|
||||
#include "pico/stdlib.h"
|
||||
#include "hardware/i2c.h"
|
||||
#include "hardware/pio.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t reg; ///< Register address
|
||||
uint8_t value; ///< Value to store
|
||||
@ -17,8 +22,8 @@ public:
|
||||
private:
|
||||
uint8_t sda;
|
||||
uint8_t scl;
|
||||
uint ctrl;
|
||||
int ctrl;
|
||||
i2c_inst_t* i2cc;
|
||||
pio_hw_t* pio;
|
||||
uint sm;
|
||||
int sm;
|
||||
};
|
||||
@ -1,5 +1,7 @@
|
||||
#include <camera.hpp>
|
||||
#include <SCCB.hpp>
|
||||
#include <camera.hpp>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
#include "../../hardware_dma/include/hardware/dma.h"
|
||||
@ -281,7 +283,7 @@ register_val_t OV2640_init[] = {
|
||||
{OV2640_REG0_R_DVP_SP, 0x02}, // Manual DVP PCLK setting
|
||||
{OV2640_REG0_RESET, 0x00}}; // Go
|
||||
// TODO: figure out how to set to JPEG and 260x260
|
||||
/*OV2640_qqvga[] =
|
||||
register_val_t OV2640_qqvga[] =
|
||||
{// Configure OV2640 for QQVGA output
|
||||
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
|
||||
{OV2640_REG0_RESET, OV2640_RESET_DVP},
|
||||
@ -300,16 +302,18 @@ register_val_t OV2640_init[] = {
|
||||
{OV2640_REG0_ZMOH, 0x1E}, // OUTH low bits
|
||||
{OV2640_REG0_ZMHH, 0x00}, // OUTW/H high bits
|
||||
{OV2640_REG0_R_DVP_SP, 0x08}, // Manual DVP PCLK setting
|
||||
{OV2640_REG0_RESET, 0x00}}, // Go
|
||||
OV2640_rgb[] = {{OV2640_REG_RA_DLMT,
|
||||
OV2640_RA_DLMT_DSP}, // DSP bank select 0
|
||||
{OV2640_REG0_RESET, 0x00}
|
||||
}; // Go
|
||||
register_val_t OV2640_rgb[] = {
|
||||
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
|
||||
{OV2640_REG0_RESET, OV2640_RESET_DVP},
|
||||
{OV2640_REG0_IMAGE_MODE, OV2640_IMAGE_MODE_DVP_RGB565 |
|
||||
OV2640_IMAGE_MODE_BYTE_SWAP},
|
||||
{0xD7, 0x03}, // Mystery init values
|
||||
{0xE1, 0x77}, // seen in other examples
|
||||
{OV2640_REG0_RESET, 0x00}}, // Go
|
||||
OV2640_yuv[] = {
|
||||
{OV2640_REG0_RESET, 0x00}
|
||||
}; // Go
|
||||
register_val_t OV2640_yuv[] = {
|
||||
{OV2640_REG_RA_DLMT, OV2640_RA_DLMT_DSP}, // DSP bank select 0
|
||||
{OV2640_REG0_RESET, OV2640_RESET_DVP},
|
||||
{OV2640_REG0_IMAGE_MODE,
|
||||
@ -317,15 +321,34 @@ OV2640_yuv[] = {
|
||||
{0xD7, 0x01}, // Mystery init values
|
||||
{0xE1, 0x67}, // seen in other examples
|
||||
{OV2640_REG0_RESET, 0x00}
|
||||
}; // Go*/
|
||||
}; // Go
|
||||
|
||||
uint8_t image_buf[3][13 * 1024];
|
||||
uint8_t image_buf[352*288*2];
|
||||
sm_dma_config_t gpios[48];
|
||||
int dma_channel;
|
||||
int sm;
|
||||
|
||||
OV2640::OV2640(camera_config_t config)
|
||||
{
|
||||
this->config = config;
|
||||
this->fb = &image_buf;
|
||||
//this->fb = &image_buf;
|
||||
}
|
||||
|
||||
// Pin interrupt on VSYNC calls this to start DMA transfer (unless suspended).
|
||||
static void vsync_irq(uint gpio, uint32_t events)
|
||||
{
|
||||
pio_sm_clear_fifos(pio2, sm);
|
||||
dma_channel_start(dma_channel);
|
||||
}
|
||||
|
||||
static void dma_finish_irq()
|
||||
{
|
||||
// Channel MUST be reconfigured each time (to reset the dest address).
|
||||
dma_channel_set_write_addr(dma_channel,
|
||||
(uint8_t *)(image_buf), false);
|
||||
dma_hw->ints0 = 1u << dma_channel; // Clear IRQ
|
||||
uint32_t data = pio2->rxf[sm];
|
||||
fwrite(&data, 1, 32, stdout);
|
||||
}
|
||||
|
||||
int OV2640::begin(int dma_irq)
|
||||
@ -341,26 +364,36 @@ int OV2640::begin(int dma_irq)
|
||||
pwm_set_enabled(slice_num, true);
|
||||
|
||||
// Init SCCB
|
||||
printf("Init SCCB\n");
|
||||
this->sccb = SCCB(this->config.pin_sccb_sda, this->config.pin_sccb_scl);
|
||||
this->sccb.begin(this->config.sccb_ctrl);
|
||||
printf("Inited SCCB\n");
|
||||
|
||||
// ENABLE AND/OR RESET CAMERA --------------------------------------------
|
||||
// Unsure of camera startup time from beginning of input clock.
|
||||
// Let's guess it's similar to tS:REG (300 ms) from datasheet.
|
||||
sleep_ms(300000);
|
||||
sleep_ms(300);
|
||||
|
||||
// Perform a soft reset (we dont wanna waste GPIO on wiring in reset pins)
|
||||
this->sccb.writeRegister(OV2640_REG_RA_DLMT, OV2640_RA_DLMT_SENSOR); // Bank select 1
|
||||
this->sccb.writeRegister(OV2640_REG1_COM7, OV2640_COM7_SRST); // System reset
|
||||
sleep_ms(1); // Datasheet: tS:RESET = 1 ms
|
||||
sleep_ms(300); // Datasheet: tS:RESET = 1 ms
|
||||
|
||||
// Init main camera settings
|
||||
printf("Write list of init\n");
|
||||
this->sccb.writeList(OV2640_init, sizeof OV2640_init / sizeof OV2640_init[0]);
|
||||
printf("Write list of qqvga\n");
|
||||
this->sccb.writeList(OV2640_qqvga, sizeof OV2640_qqvga / sizeof OV2640_qqvga[0]);
|
||||
printf("Write list of rgb\n");
|
||||
this->sccb.writeList(OV2640_rgb, sizeof OV2640_rgb / sizeof OV2640_rgb[0]);
|
||||
|
||||
|
||||
printf("Gpio init\n");
|
||||
gpio_init(this->config.pin_pclk);
|
||||
gpio_set_dir(this->config.pin_pclk, GPIO_IN);
|
||||
gpio_init(this->config.pin_vsync);
|
||||
gpio_set_dir(this->config.pin_vsync, GPIO_IN);
|
||||
gpio_pull_down(this->config.pin_vsync);
|
||||
gpio_init(this->config.pin_href);
|
||||
gpio_set_dir(this->config.pin_href, GPIO_IN);
|
||||
for (uint8_t i = 0; i < 8; i++)
|
||||
@ -368,19 +401,21 @@ int OV2640::begin(int dma_irq)
|
||||
gpio_init(this->config.pin_data_base + i);
|
||||
gpio_set_dir(this->config.pin_data_base + i, GPIO_IN);
|
||||
}
|
||||
printf("Gpio init done\n");
|
||||
|
||||
// PIO periph to use is currently specified by the user in the arch struct,
|
||||
// but I suppose this could be written to use whatever PIO has resources.
|
||||
|
||||
// Mask the GPIO pin used PCLK into the PIO opcodes -- see notes at top
|
||||
// TODO: check if this is correct (code made for rp2040 not rp2350 so it might differ)
|
||||
printf("PIO init\n");
|
||||
capture_pio_opcodes[0] |= (this->config.pin_href & 31);
|
||||
capture_pio_opcodes[1] |= (this->config.pin_pclk & 31);
|
||||
capture_pio_opcodes[3] |= (this->config.pin_pclk & 31);
|
||||
|
||||
uint offset = pio_add_program(pio2, &cap_pio_program);
|
||||
this->sm = pio_claim_unused_sm(pio2, true); // 0-3
|
||||
|
||||
sm = this->sm;
|
||||
pio_sm_set_consecutive_pindirs(pio2, this->sm, this->config.pin_data_base, 8, false);
|
||||
|
||||
pio_sm_config c = pio_get_default_sm_config();
|
||||
@ -393,11 +428,12 @@ int OV2640::begin(int dma_irq)
|
||||
|
||||
pio_sm_init(pio2, this->sm, offset, &c);
|
||||
pio_sm_set_enabled(pio2, this->sm, true);
|
||||
printf("PIO init done\n");
|
||||
|
||||
// SET UP DMA ------------------------------------------------------------
|
||||
|
||||
printf("DMA init\n");
|
||||
this->dma_channel = dma_claim_unused_channel(false); // don't panic
|
||||
|
||||
dma_channel = this->dma_channel;
|
||||
this->dma_config = dma_channel_get_default_config(this->dma_channel);
|
||||
channel_config_set_transfer_data_size(&this->dma_config, DMA_SIZE_16);
|
||||
channel_config_set_read_increment(&this->dma_config, false);
|
||||
@ -416,7 +452,7 @@ int OV2640::begin(int dma_irq)
|
||||
|
||||
// Set up end-of-DMA interrupt
|
||||
dma_channel_set_irq0_enabled(this->dma_channel, true);
|
||||
|
||||
printf("DMA init done\n");
|
||||
//? setup diffrent handlers for each cam???
|
||||
//? check with a button or smth if this fires all events or only one
|
||||
//? cuz then I would be able to do dma_finish_irq_cam1, dma_finish_irq_cam2, dma_finish_irq_cam3
|
||||
@ -428,29 +464,17 @@ int OV2640::begin(int dma_irq)
|
||||
//? This also could be redone with hardcoded values
|
||||
gpio_set_irq_enabled_with_callback(this->config.pin_vsync, GPIO_IRQ_EDGE_RISE, true,
|
||||
&vsync_irq);
|
||||
|
||||
printf("IRQ init done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Pin interrupt on VSYNC calls this to start DMA transfer (unless suspended).
|
||||
static void vsync_irq(uint gpio, uint32_t events)
|
||||
{
|
||||
pio_sm_clear_fifos(pio2, archptr->sm);
|
||||
dma_channel_start(archptr->dma_channel);
|
||||
}
|
||||
|
||||
static void dma_finish_irq()
|
||||
{
|
||||
// Channel MUST be reconfigured each time (to reset the dest address).
|
||||
dma_channel_set_write_addr(archptr->dma_channel,
|
||||
(uint8_t *)(image_buf), false);
|
||||
dma_hw->ints0 = 1u << archptr->dma_channel; // Clear IRQ
|
||||
}
|
||||
|
||||
//! 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
|
||||
/* Read the flags
|
||||
pio0_hw->irq;
|
||||
uint32_t flags = read_register(PIO0_BASE, PIO_IRQ_OFFSET)
|
||||
// Check the flags to determine which state machine made the request
|
||||
if (flags & 0b0001) { handle_sm_0(); }
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
#include <cstdint>
|
||||
#include "pico/stdlib.h"
|
||||
#include "../../hardware_dma/include/hardware/dma.h"
|
||||
// TODO: Add XCLK settings
|
||||
typedef struct {
|
||||
int pin_pwdn; /*!< GPIO pin for camera power down line */ //? Also called PWDN, or set to -1 and tie to GND
|
||||
@ -14,8 +17,8 @@ typedef struct {
|
||||
} camera_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint sm;
|
||||
uint dma_channel;
|
||||
int sm;
|
||||
int dma_channel;
|
||||
} sm_dma_config_t;
|
||||
|
||||
|
||||
@ -29,8 +32,8 @@ private:
|
||||
camera_config_t config;
|
||||
SCCB sccb;
|
||||
uint8_t* (*fb)[3];
|
||||
uint sm;
|
||||
uint dma_channel;
|
||||
int sm;
|
||||
int dma_channel;
|
||||
dma_channel_config dma_config;
|
||||
};
|
||||
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#include "pio_i2c.hpp"
|
||||
#include "pio_i2c.h"
|
||||
#include "i2c.pio.h"
|
||||
|
||||
const int PIO_I2C_ICOUNT_LSB = 10;
|
||||
const int PIO_I2C_FINAL_LSB = 9;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user