Thanks, I should have verified those as well. I did verify that the D pins were all on one GPIO port, so could do DMA, and as PCLK is on an XBAR pin, another option was to use the DMA code we were playing with for the OV7670, especially depending on maybe how well you can control the signals. For me another issue with their breakout boards is it looks pretty difficult to setup to intercept the different signals to hook up LA or Scope to.The tentative plan for Himax HM01B0 camera support is to use FlexIO2, similar to AN12686. I'll attach the PDF to this message.
Code:HM01B0 pin pin# NXP Usage ---------- ---- --- ----- FVLD/VSYNC 33 EMC_07 GPIO LVLD/HSYNC 32 B0_12 FlexIO2:12 MCLK 7 B1_01 PWM PCLK 8 B1_00 FlexIO2:16 D0 40 B0_04 FlexIO2:4 D1 41 B0_05 FlexIO2:5 D2 42 B0_06 FlexIO2:6 D3 43 B0_07 FlexIO2:7 D4 44 B0_08 FlexIO2:8 - probably not needed, use 4 bit mode D5 45 B0_09 FlexIO2:9 - probably not needed, use 4 bit mode D6 6 B0_10 FlexIO2:10 - probably not needed, use 4 bit mode D7 9 B0_11 FlexIO2:11 - probably not needed, use 4 bit mode TRIG 5 EMC_08 ??? INT 29 EMC_31 ??? SCL 19 AD_B1_0 I2C SDA 18 AD_B1_1 I2C
Initialize USB drive...UsbBase::mscBegin called 20006da0 1 1
After usbDriveBegin
Blocks: 62552063 Size: 512
msc # Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
exFAT: 1,0,0x20,0x21,0x0,0x7,0xFE,0xFF,0xFF,2048,30044160
exFAT: 2,0,0x20,0x21,0x0,0x7,0xFE,0xFF,0xFF,30046208,32505856
pt_#0: 3,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0: 4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
drive 0 Partition 0 valid:1
drive 0 Partition 1 valid:1
Initialize USB drive...UsbBase::mscBegin called 200076a0 1 1
After usbDriveBegin
Blocks: 242024447 Size: 512
msc # Partition Table
part,boot,bgnCHS[3],type,endCHS[3],start,length
exFAT: 1,0,0x20,0x21,0x0,0x7,0xFE,0xFF,0xFF,2048,242024447
pt_#0: 2,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0: 3,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
pt_#0: 4,0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0,0
drive 1 Partition 0 valid:1
Initialize SDIO SD card...initialization failed.
Initialize SPI SD card...initialization failed.
***** Partition List *****
0(0:1):>> ExFat: Volume name:(v1) Partition Total Size:15365832704 Used:13107200 time us: 22752
1(0:2):>> ExFat: Partition Total Size:16626221056 Used:7340032 time us: 24505
2(1:1):>> ExFat: Partition Total Size:123882831872 Used:2413953024 time us: 87129
done...
Commands:
f <partition> [16|32|ex] - to format
v <partition> <label> - to change volume label
d <partition> - to dump first sectors
p <partition> - print Partition info
l <partition> - to do ls command on that partition
c - toggle on/off format show changed data
*** Danger Zone ***
N <USB Device> start_addr <length> - Add a new partition to a disk
R <USB Device> - Setup initial MBR and format disk *sledgehammer*
X <partition> [d <usb device> - Delete a partition
Paul Question, which probably you may not be able to answer. Wondering if these are Beta boards in the sense that they may take some of our inputs here to help maybe make a final release with potential updates.
Example: As mentioned earlier in this thread, it feels like they should easily be able to get at least two more signals out on the RTS and CTS pins? I have not checked the other unused pins on the connector to see if maybe others.
@mjs513 - can you list the current github'ery needed for MSC/MTP/USB_HOST/??? as needed to get current with that?
Think that is right.Ok:
MTP-T4: https://github.com/KurtE/MTP_t4/tree/test_msc_parts
USBHost_t36: https://github.com/KurtE/USBHost_t36/tree/MSC_read_sectors_cb
MSC: https://github.com/wwatson4506/UsbMscFat
Think I got it all
// turn on power to camera (1.8V - might be an issue?)
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
delay(10);
// turn on MCLK
analogWriteFrequency(7, 12000000);
analogWrite(7, 128);
delay(1);
It should be interesting! Will be fun to see what your adapter is:I got the camera to start answering I2C with the Wire scanner example. This is needed to turn make the camera respond.
Code:// turn on power to camera (1.8V - might be an issue?) pinMode(2, OUTPUT); digitalWrite(2, HIGH); delay(10); // turn on MCLK analogWriteFrequency(7, 12000000); analogWrite(7, 128); delay(1);
void OV767X::beginXClk()
{
// Generates 8 MHz signal using PWM... Will speed up.
analogWriteFrequency(_xclkPin, 16000000);
analogWrite(_xclkPin, 127); delay(100); // 9mhz works, but try to reduce to debug timings with logic analyzer
}
Hey guys, is the USB-C connector for programming on the microMod board itself or are those pins brought out the the M.2 connector?
Hey guys, is the USB-C connector for programming on the microMod board itself or are those pins brought out the the M.2 connector? Being able to to do our own USB connector on a custom carrier board for commercial applications would be great.
void loop()
{
digitalToggleFast(D0);
delay(600); // much blinkier that (1)
mmBus = 0xff; // write 8bit value to bus
digitalToggleFast(D0);
delay(600); // much blinkier that (1)
mmBus = 0x00; // write 8bit value to bus
}
Great, thanks for testing@luni - mmBus works on ATP pins G0-G7:
Followed KurtE's link and the screw is only noted as " screw 4mm
Well since you asked if you use the display carrier board it kind of sort of works:@mjs513 - sounds like the display adapter board should work with ILI9341's?
analogWrite(3, 128);
Great, thanks for testing
Its a standard M2.5 thread.
Well since you asked if you use the display carrier board it kind of sort of works:
...
Along with making sure
CS = 4
DC = 5
RST = 42
and since it uses PWM need this is setup
Code:analogWrite(3, 128);
Pin 3 is the backlight pin.
The display is Hyperdisplay9341. Its probably all in the configure but didn't look closely enough.
https://github.com/sparkfun/HyperDisplay_4DLCD-320240_ArduinoLibrary
Along with that library you need 2 other libraries and it uses their PIN Notation. They even have their own SPI library.
I know I just tried it.
#include <Wire.h>
elapsedMicros vsync_usec;
void setup()
{
Wire.begin();
Serial.begin(9600);
while (!Serial) ;
Serial.println("HM01B0 Camera Test");
Serial.println("------------------");
// turn on power to camera (1.8V - might be an issue?)
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
delay(10);
// turn on MCLK
analogWriteFrequency(7, 6000000);
analogWrite(7, 128);
delay(1);
pinMode(33, INPUT_PULLDOWN); // VSYNC Pin
if (hm01b0_detect()) {
Serial.println("HM01B0 Camera Detected :-)");
} else {
Serial.println("No HM01B0 Camera Found");
return;
}
//hm01b0_write(0x3059, 0x00); // use 8 bit mode, D0-D7
hm01b0_write(0x3059, 0x40); // use 4 bit mode, D0-D3
//hm01b0_write(0x3059, 0x20); // use serial mode, D0 only
hm01b0_write(0x3060, 0x00); // slowest clock div
hm01b0_write(0x0100, 0x01); // turn on, continuous streaming mode
vsync_usec = 0;
}
bool hm01b0_detect()
{
if (hm01b0_read(0) != 0x01) return false;
if (hm01b0_read(1) != 0xB0) return false;
return true;
}
void hm01b0_write(uint16_t addr, uint8_t data)
{
Wire.beginTransmission(0x24);
Wire.write(addr >> 8);
Wire.write(addr);
Wire.write(data);
if (Wire.endTransmission() != 0) {
Serial.println("error writing to HM01B0");
}
}
uint8_t hm01b0_read(uint16_t addr)
{
Wire.beginTransmission(0x24);
Wire.write(addr >> 8);
Wire.write(addr);
if (Wire.endTransmission(false) != 0) {
Serial.println("error reading HM01B0, address");
return 0;
}
if (Wire.requestFrom(0x24, 1) < 1) {
Serial.println("error reading HM01B0, data");
return 0;
}
return Wire.read();
}
void loop()
{
static int prior_vsync = LOW;
int vsync = digitalRead(33);
if (prior_vsync == LOW && vsync == HIGH) {
uint32_t us = vsync_usec;
vsync_usec = 0;
Serial.print("VSYNC event: ");
Serial.print(1000000.0f / (float)us);
Serial.println(" Hz");
}
prior_vsync = vsync;
}
/*
HM01B0 pin pin# NXP Usage
---------- ---- --- -----
FVLD/VSYNC 33 EMC_07 GPIO
LVLD/HSYNC 32 B0_12 FlexIO2:12
MCLK 7 B1_01 PWM
PCLK 8 B1_00 FlexIO2:16
D0 40 B0_04 FlexIO2:4
D1 41 B0_05 FlexIO2:5
D2 42 B0_06 FlexIO2:6
D3 43 B0_07 FlexIO2:7
D4 44 B0_08 FlexIO2:8 - probably not needed, use 4 bit mode
D5 45 B0_09 FlexIO2:9 - probably not needed, use 4 bit mode
D6 6 B0_10 FlexIO2:10 - probably not needed, use 4 bit mode
D7 9 B0_11 FlexIO2:11 - probably not needed, use 4 bit mode
TRIG 5 EMC_08 ???
INT 29 EMC_31 ???
SCL 19 AD_B1_0 I2C
SDA 18 AD_B1_1 I2C
*/
Not sure if you have this library from Sparkfun:
Yeah, saw that. The code is in so many files with so much extraneous abstraction layer stuff that it was simpler just to write minimal code from scratch. Maybe we'll use that library eventually, but pretty much everything about is the exact opposite how my preferred coding style, so I can't say I'm excited about it.
#define HM01B0_DEFAULT_ADDRESS (0x24)
struct regval_entry {
uint16_t reg_num;
uint8_t value;
};
static const regval_entry hb_reg_name_table[] =
{
// ;*************************************************************************
// ; Sensor: HM01B0
// ; I2C ID: 24
// ; Resolution: 324x244
// ; Lens:
// ; Flicker:
// ; Frequency:
// ; Description: AE control enable
// ; 8-bit mode, LSB first
// ;
// ;
// ; Note:
// ;
// ; $Revision: 1338 $
// ; $Date:: 2017-04-11 15:43:45 +0800#$
// ;*************************************************************************
//
// // ---------------------------------------------------
// // HUB system initial
// // ---------------------------------------------------
// W 20 8A04 01 2 1
// W 20 8A00 22 2 1
// W 20 8A01 00 2 1
// W 20 8A02 01 2 1
// W 20 0035 93 2 1 ; [3]&[1] hub616 20bits in, [5:4]=1 mclk=48/2=24mhz
// W 20 0036 00 2 1
// W 20 0011 09 2 1
// W 20 0012 B6 2 1
// W 20 0014 08 2 1
// W 20 0015 98 2 1
// ;W 20 0130 16 2 1 ; 3m soc, signal buffer control
// ;W 20 0100 44 2 1 ; [6] hub616 20bits in
// W 20 0100 04 2 1 ; [6] hub616 20bits in
// W 20 0121 01 2 1 ; [0] Q1 Intf enable, [1]:4bit mode, [2] msb first, [3] serial mode
// W 20 0150 00 2 1 ;
// W 20 0150 04 2 1 ;
//
//
// //---------------------------------------------------
// // Initial
// //---------------------------------------------------
// W 24 0103 00 2 1 ; software reset-> was 0x22
{0x0103, 0x00},
// W 24 0100 00 2 1; power up
{0x0100, 0x00},
//
//
//
// //---------------------------------------------------
// // Analog
// //---------------------------------------------------
// L HM01B0_analog_setting.txt
{0x1003, 0x08},
{0x1007, 0x08},
{0x3044, 0x0A},
{0x3045, 0x00},
{0x3047, 0x0A},
{0x3050, 0xC0},
{0x3051, 0x42},
{0x3052, 0x50},
{0x3053, 0x00},
{0x3054, 0x03},
{0x3055, 0xF7},
{0x3056, 0xF8},
{0x3057, 0x29},
{0x3058, 0x1F},
{0x3059, 0x1E},
{0x3064, 0x00},
{0x3065, 0x04},
//
//
// //---------------------------------------------------
// // Digital function
// //---------------------------------------------------
//
// // BLC
// W 24 1000 43 2 1 ; BLC_on, IIR
{0x1000, 0x43},
// W 24 1001 40 2 1 ; [6] : BLC dithering en
{0x1001, 0x40},
// W 24 1002 32 2 1 ; // blc_darkpixel_thd
{0x1002, 0x32},
//
// // Dgain
// W 24 0350 7F 2 1 ; Dgain Control
{0x0350, 0x7F},
//
// // BLI
// W 24 1006 01 2 1 ; [0] : bli enable
{0x1006, 0x01},
//
// // DPC
// W 24 1008 00 2 1 ; [2:0] : DPC option 0: DPC off 1 : mono 3 : bayer1 5 : bayer2
{0x1008, 0x00},
// W 24 1009 A0 2 1 ; cluster hot pixel th
{0x1009, 0xA0},
// W 24 100A 60 2 1 ; cluster cold pixel th
{0x100A, 0x60},
// W 24 100B 90 2 1 ; single hot pixel th
{0x100B, 0x90},
// W 24 100C 40 2 1 ; single cold pixel th
{0x100C, 0x40},
// //
// advance VSYNC by 1 row
{0x3022, 0x01},
// W 24 1012 00 2 1 ; Sync. enable VSYNC shift
{0x1012, 0x01},
//
// // ROI Statistic
// W 24 2000 07 2 1 ; [0] : AE stat en [1] : MD LROI stat en [2] : MD GROI stat en [3] : RGB stat ratio en [4] : IIR selection (1 -> 16, 0 -> 8)
{0x2000, 0x07},
// W 24 2003 00 2 1 ; MD GROI 0 y start HB
{0x2003, 0x00},
// W 24 2004 1C 2 1 ; MD GROI 0 y start LB
{0x2004, 0x1C},
// W 24 2007 00 2 1 ; MD GROI 1 y start HB
{0x2007, 0x00},
// W 24 2008 58 2 1 ; MD GROI 1 y start LB
{0x2008, 0x58},
// W 24 200B 00 2 1 ; MD GROI 2 y start HB
{0x200B, 0x00},
// W 24 200C 7A 2 1 ; MD GROI 2 y start LB
{0x200C, 0x7A},
// W 24 200F 00 2 1 ; MD GROI 3 y start HB
{0x200F, 0x00},
// W 24 2010 B8 2 1 ; MD GROI 3 y start LB
{0x2010, 0xB8},
//
// W 24 2013 00 2 1 ; MD LRIO y start HB
{0x2013, 0x00},
// W 24 2014 58 2 1 ; MD LROI y start LB
{0x2014, 0x58},
// W 24 2017 00 2 1 ; MD LROI y end HB
{0x2017, 0x00},
// W 24 2018 9B 2 1 ; MD LROI y end LB
{0x2018, 0x9B},
//
// // AE
// W 24 2100 01 2 1 ; [0]: AE control enable
{0x2100, 0x01},
// W 24 2104 07 2 1 ; converge out th
{0x2104, 0x07},
// W 24 2105 0C 2 1 ; max INTG Hb
{0x2105, 0x0C},
// W 24 2106 78 2 1 ; max INTG Lb
{0x2106, 0x78},
// W 24 2108 03 2 1 ; max AGain in full
{0x2108, 0x03},
// W 24 2109 03 2 1 ; max AGain in bin2
{0x2109, 0x03},
// W 24 210B 80 2 1 ; max DGain
{0x210B, 0x80},
// W 24 210F 00 2 1 ; FS 60Hz Hb
{0x210F, 0x00},
// W 24 2110 85 2 1 ; FS 60Hz Lb
{0x2110, 0x85},
// W 24 2111 00 2 1 ; Fs 50Hz Hb
{0x2111, 0x00},
// W 24 2112 A0 2 1 ; FS 50Hz Lb
{0x2112, 0xA0},
//
//
// // MD
// W 24 2150 03 2 1 ; [0] : MD LROI en [1] : MD GROI en
{0x2150, 0x03},
//
//
// //---------------------------------------------------
// // frame rate : 5 FPS
// //---------------------------------------------------
// W 24 0340 0C 2 1 ; smia frame length Hb
{0x0340, 0x0C},
// W 24 0341 7A 2 1 ; smia frame length Lb 3192
{0x0341, 0x7A},
//
// W 24 0342 01 2 1 ; smia line length Hb
{0x0342, 0x01},
// W 24 0343 77 2 1 ; smia line length Lb 375
{0x0343, 0x77},
//
// //---------------------------------------------------
// // Resolution : QVGA 324x244
// //---------------------------------------------------
// W 24 3010 01 2 1 ; [0] : window mode 0 : full frame 324x324 1 : QVGA
{0x3010, 0x01},
//
//
// W 24 0383 01 2 1 ;
{0x0383, 0x01},
// W 24 0387 01 2 1 ;
{0x0387, 0x01},
// W 24 0390 00 2 1 ;
{0x0390, 0x00},
//
// //---------------------------------------------------
// // bit width Selection
// //---------------------------------------------------
// W 24 3011 70 2 1 ; [0] : 6 bit mode enable
{0x3011, 0x70},
//
//
// W 24 3059 02 2 1 ; [7]: Self OSC En, [6]: 4bit mode, [5]: serial mode, [4:0]: keep value as 0x02
{0x3059, 0x02},
// W 24 3060 01 2 1 ; [5]: gated_clock, [4]: msb first,
{0x3060, 0x20},
// ; [3:2]: vt_reg_div -> div by 4/8/1/2
// ; [1;0]: vt_sys_div -> div by 8/4/2/1
//
//
{0x0101, 0x01},
// //---------------------------------------------------
// // CMU update
// //---------------------------------------------------
//
// W 24 0104 01 2 1 ; was 0100
{0x0104, 0x01},
//
//
//
// //---------------------------------------------------
// // Turn on rolling shutter
// //---------------------------------------------------
// W 24 0100 01 2 1 ; was 0005 ; mode_select 00 : standby - wait fir I2C SW trigger 01 : streaming 03 : output "N" frame, then enter standby 04 : standby - wait for HW trigger (level), then continuous video out til HW TRIG goes off 06 : standby - wait for HW trigger (edge), then output "N" frames then enter standby
{0x0100, 0x00},
//
// ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
};
void cameraWriteRegister(uint16_t reg, uint8_t data) {
Wire.beginTransmission(HM01B0_DEFAULT_ADDRESS);
Wire.write(addr >> 8);
Wire.write(addr);
Wire.write(data);
uint8_t status = Wire.endTransmission();
if (status != 0) {
Serial.printf("Write Register:%x = %x failed: %d\n", reg, data, status);
}
}
// simplified test for end of reglist is reg_num == 0xFF
// This will have to change if we ever get a camera with
// 255 or more registers!
void cameraWriteRegList(struct regval_entry reglist[]) {
uint16_t index = 0;
uint16_t reg_addr; uint8_t reg_val;
while (reglist[index].reg_num != 0xFFFF) {
reg_addr = reglist[index].reg_num;
reg_val = reglist[index].value;
cameraWriteRegister(reg_addr, reg_val);
delayMicroseconds(100);
index++;
}
}