QHYCCD

QHY5L-II Low Level (1) USB Protocol

QiuHY

  • *****
  • 5005
    • View Profile
    • Email
QHY5L-II Low Level (1) USB Protocol
« on: February 16, 2017, 09:58:58 PM »
VendRequest Command

VendRequest 0xd1    Write Command to Camera
VendRequest 0xd2    Read Camera Status Information


VendRequest command is using the control endpoint to transfer the data. Normally it includes the following parameter of the control transfer:

request type
request 
index
value
buffer
length
timeout


for vendrequest 0xd1, the parameter is:
requestType=0x40
vend request command=0xd1
value =0x00
index =0x00
length is 16byte
the buffer is the data that you want to send camera. It includes 16byte:

Byte0........Byte15



for vendrequest 0xd2, the parameter is
requestType=0xc0
vend request command=0xd2
value =0x00
index =0x00
length is 64byte

the buffer is the information you read from the camera it has 64byte:
Byte0......Byte63
« Last Edit: February 27, 2017, 11:58:42 AM by QiuHY »
Qiu Hongyun

robz

QHY5L-II-M/C LOW LEVEL PPROTOCOL (LEVEL 1)
« Reply #1 on: February 23, 2017, 12:44:47 AM »
1.QHY5L-II-M/C LOW LEVEL PPROTOCOL  (LEVEL 1)

LEVEL 0 refers to our original FIREWARE interface
LEVEL 1 is more unified interface is based on LEVEL 0.

2. LEVEL 1 INTERFACE DESCRIPTION

This interface include command 0xD1 and 0xD2 whitch are basic Vender Request commands.
0xD1: Direction is out (computer send command to camera)
          Length is 16 bytes
0xD2:Direction is IN (computer requrest camera to submit it's some status)
         Length is 64 bytes.

Their Index and Value in vender request are not used. So you can set to 0X0000.

3. COMMAND 0xD1 DESCRIPTION

Camera Control Command:
It is defined as command type . It tell camera do what.  It locate in 1th byte in transfer data(16 bytes).
Camera Control Parameter:
This is command parameter. It locate in the 2th to 16th

Data Format:
Byte0                        Camera Control Command(CCC)
Byte1......Byte15        Camera Control Parameter(CCP1...15)


3.1.  CCC=0XA0
Camera Initialization, After perform this command,The camera will be set to a known status.

CCP1        0=streaming.    1=single frame capture .
CCP2...3   Pixel Binning is In X direction (CCP2=MSB, CCP3=LSB)    current 0618 firmware does not support binning
CCP4...5   Pixel Binning is In Y direction   (CCP4=MSB,CCP5=LSB)     current 0618 firemware does not support binning


Note1: After init to steaming mode, the camera will start to send out the video streaming at 1280*960, 8bit , 20ms exposure

Note2: After init to the single frame mode, the camera will enter a idle status and wait the exposure . The default is 1280*960 8bit .  You can use CCC=0XA6 CCP1=0X00 to start a single frame capture

3.2. CCC=0XA1   

Set Camera Readout Speed.
You can use this command to optimize readout noise and balance the transfer speed
whitch let the camera and computer have a normal transfer.

CCP1 : Readout Speed value
0x00:12Mhz
0x01:24Mhz
0x02:48Mhz



3.3. CCC=0XA2 
Select Camera Resolution and set the ROI.

CCP1     Reserved , no use,  can be set to 0x00
CCP2..3  ROI X size (CCP2=MSB  CCP3=LSB)
CCP4..5  ROI X start
CCP6..7  ROI Y size( CCP4=MSB   CCP5=LSB)
CCP8..9  ROI Y start

QHY5L-II support the anysize ROI.

3.4. CCC=0XA3
Set Exposure Time

CCP1..4   32BIT exposure time,the unit is microsecond(us)    CCP1=MSB  CCP4=LSB



Note: The camera has two mode. Long exposure mode and short exposure mode. The time switch point is about 1sec to 2sec or more (will be different with the USB traffic size).  The camera firmware will switch this two mode automatically. But when it switch from long exposure to short exposure. it may cause some delay (about 1-2sec or more). So you need to just wait it. Do not need call it again.


3.5. CCC=0XA4
Gain Setting

Analog Gain R(CCP1..CCP2)
CCP1 ~ CCP2 :
The Analog Gain have eight levels.
value  mean
0x0002  1x       
0x0003  1.25x     
0x0006  2x
0x0007  2.5x     
0x000a  4x           
0x000b  5x
0x000e  8x
0x000f   10x

Digital Gain R(CCP3..CCP4)  CCP3 is MSB  CCP4 is LSB.   Range 0-255
value = Digital Gain R*0.03125


Analog Gain G(CCP5..6)
Analog Gain G should be set to the same value of Analog Gain R

Digital Gain G(CCP7..CCP8)  CCP7=MSB  CCP8=LSB
value=DigitalGainG*0.03125


Analog Gain B(CCP9..10)
Analog Gain B should be set to the same value of Analog Gain R


Digital Gain B(CCP11..CCP12)    CCP11=MSB    CCP12=LSB
value=DigitalGainB*0.03125



Because the total gain = analog gain * digital gain. In order to keep the image can reach saturate . The digital gain should be at least 32  to make the value =32*0.03125=1.

For Mono Camera. All analog gain need to be set to same value.  And all digital gain need to be set to the same value.
For Color Camera. All analog gain need to be set to same value.  Digital gain can be set to different value to do the color balance.



3.6. CCC=0XA5
usb traffic setting

CCP1  USB  tarffic value:
min 0  max 255

Increase the USB traffic will increase the line period and reduce the average USB bandwidth. In some slow computer , there is a lot bad frame and cause the FPS is very small. When increase this usb traffic the bad frame will become less and the FPS will increase.


3.7. CCC=0XA6
   CCP1 0X00: Start streaming
          0x11: Stop long exposure and can read out the image.
          0x22: enter sleep (in SLEEP,we can save power, holding the register value,need not to initialize the cmos after wake up)
          0x44: wake up
          0x66: reset CMOS
          0xFF: Stop Continuous streaming  (not avalible in 0618 HEX)

3.8. CCC=0XA7
Set Image depth

CCP1=0    8BIT
CCP1=1  16BIT

3.9. CCC=0XA8
Set offset

CCP1..2  16bit OFFSET

3.10. CCC=0XAB
Guiding port control
meaning    CCP1 | CCP2
RA+          01  |  80
RA-          01  |  10
DEC+            02  |  40
DEC-               02  |  20
RA+,DEC+     03  |  C0
RA+,DEC       03  |  A0
RA-,DEC+      03  |  50
RA-,DEC        03  |  30
ALL OFF         03  |  00


Warn: In streaming mode since this CMOS sensor is free running, It may not be sync with the guide route and sometimes it may cause the problem. For example, during the calibration progress, the CMOS is under long exposure but you you send the calibration signal from guide port. It will cause the star become a line , not a dot. Will cause the software can not detect the center of the star position. So that it need to be very careful to do this. Maybe use the single frame mode is much better.




4. COMMAND 0xD2 DESCRIPTION
Return camera status
0xD2 include 64 bytes Camera Statu Information(CSI)
CSI0     cmos speed,uint is Mhz
CSI1..4   The remaining exposure time,the unit is us. CSI1=MSB  CSI4=LSB
CSI5..8  target exposure time

CSI46      QHY5-II sub model

QHY5-II sub model define:
0: no QHY5-II camera found
1:QHY5-II
2.QHY5T-II
3:QHY5V-II
4.QHY5U-II
5.QHY5P-II
6.QHY5L-II
7.QHY5X-II
8.QHY5F-II
9.QHY5R-II
10.QHY5N-II

CSI47     sensor color/mono type
COLOR/MONO define
0: mono
1: RGB
2: CMYG
3. RGBW

CSI48...63 camera serial number(16 bytes)






Image Readout

The EndPoint that using for image data readout is 0X82



« Last Edit: May 14, 2017, 10:53:58 AM by QiuHY »

robz

Re: QHY5L-II Low Level USB Protocol
« Reply #2 on: February 23, 2017, 12:50:56 AM »
This is the firmware for LEVEL 1


Compatible with QHYCCD Low level (1) usb protocol standard
« Last Edit: March 12, 2017, 09:35:05 PM by robz »

robz

Re: QHY5L-II Low Level USB Protocol
« Reply #3 on: February 23, 2017, 12:56:57 AM »
NOTE: YOU MUST SET 0XA1 AND 0XA5 BEFORE SET 0XA3. IF NOT THE EXPOSURE TIME WILL BE INCORRECT

QiuHY

  • *****
  • 5005
    • View Profile
    • Email
Re: QHY5L-II Low Level (1) USB Protocol
« Reply #4 on: April 25, 2017, 01:03:17 PM »
Hello,

        Here is the QHY5L-II new HEX ver 2017.4.26. Here is the update list:

1. Fixed the exposure time setting issue . For short exposure it can be set correctly.
2. Even changed the USB tranffic , CMOS clock, the exposure time will keep previous valoue
3. Fixed the ROI issue. We have tested the ROI for 1280*960 and 1024*768, in both 16bit and 8bit mode , it works well
4. After the init, the camera will be set to 1280*960 output, 8bit mode. And USB Traffic=30, exposure =20ms.

The TO-DO part:

1.Long exposure time still has not the same with the input value. Need to fix later.
2.We have not confirmed if the ROI changed or 8BIT/16BIT changed, if the exposure will keep constant.


Best regards,
Qiu Hongyun
Qiu Hongyun

QiuHY

  • *****
  • 5005
    • View Profile
    • Email
Re: QHY5L-II Low Level (1) USB Protocol
« Reply #5 on: May 10, 2017, 09:42:11 PM »
Hello,

         Here is an update firmware.  This firmware allow the camera start video steaming immediately after the send 0xA0 command. No need send the 0XA6 at this time.

         You can send either 0xA6 or not after init to the video streaming mode.


Best regards,
Qiu Hongyun
Qiu Hongyun

QiuHY

  • *****
  • 5005
    • View Profile
    • Email
Re: QHY5L-II Low Level (1) USB Protocol
« Reply #6 on: May 14, 2017, 05:02:53 AM »
Single Frame Mode Supported in this version

To use the single frame mode please do like this:

1.init camera with CCC=0XA1 and the CCP1=0x01  The camera will in idle statu and wait the begin exposure command.
2.you can set exposure, gain and any other parameter like 8bit/16bit, ROI etc.
3.send begin capture command CCC=0XA6 CCP=0X00
4.camera will capture one frame and send data back. You need to begin to read USB immdiately after you do step 3
5.camera will enter idle statu after all data is send out. 

6. if you want to capture a new frame  you can do step 4 and step5 again.



For the data structure that read back:

it is two conditions:

1). If the image size is the multiple of 512

The readout back is

5byte (with a pktend) -----  one frame data+5byte (with a pktend)


2) if the image size is not multiple of 512byte

5byte(with a pktend) ------   one frame data (with a pktend) ----5 byte (with a pktend)



For example:


for 1280*960 8bit , it is

5(pktend)  1228805(pktend)

for 800*600 it is

5(pktend) 480000(pktend) 5(pktend)


You can use first 5 byte and last 5 byte to verify if one frame is a good frame or not.  If there is packet lost during transfer, the image data will be less than it should be . then the data size between first 5 byte to last 5 byte should less than one frame size.

The five byte is the image head. For QHY5L-II the five byte is
0xaa 0x11 0xcc 0xee 0xxx  (last byte is not a fixed value)





Use 0XD2 to readout how many time left to the end of exposure

For long exposure we need to know the status that how long to the end. You can read 0xD2 during the long exposure to get this information. (You may need open another thread to read 0xD2 , or put the readout in another thread).  The unit is microseconds.


Force stop during long exposure and readout
You can send CCC=0XA6  CCP1=0X11 to force stop the long exposure . after exposure forced stop, camera will still send back the image data.


In this version the long exposure time is calibrated to 0.5% accurate of the total exposure time
And both 12MHz,24MHz,48MHz is tested

Please note in 16bit mode it is best to use 12MHz.  48MHz can not work. and 24MHz has very high bandwidth and we do not recommand to use it.



LED Indicator

To help the debug. You can watch the LED of the QHY5L-II to check the status:

When Firmware download to camera. The LED will be on
When init camera to streaming mode, the LED will flash. (The flash speed is the frame rate divide 2)
When init camrea to single frame mode and camera is in idle status,The LED will be off
When start one single frame exposure,  if the camera is work in short exposure mode, the LED will flash one time and if the camera is working in long exposure mode the LED will be on twice. First the LED on is the camera is doing a long exposure and secondary LED on is the camera is readout the data.




   
Some Sample Codes:

1.Use USB Sync Read under windows with QHYCCDSDK function




Code: [Select]

First you need to init the camera with CCC_A0(1,0,0)
Then use CCC_A6(0X00) to start one frame.
And then readUSB . 

void __fastcall TForm1::Button32Click(TObject *Sender)
{
int read1,read2,read3,read4,read5,read6;


unsigned char ImgHead1[5];
unsigned char ImgHead2[5];

CCC_A6(0);


read1 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,8000);  //8000 is the timeout unit ms  for long exposure you need to handle this by some other better way.
memcpy(ImgHead1,ImgDataA,5);
read2 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,8000);
read3 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,8000);
memcpy(ImgHead2,ImgDataA,5);
//read4 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960*2,ImgDataA,8000);
//read5 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960*2,ImgDataA,8000);
//read6 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960*2,ImgDataA,8000);


debug_print "head1     " + AnsiString(ImgHead1[0])+" "+AnsiString(ImgHead1[1])+" "+AnsiString(ImgHead1[2])+" "+AnsiString(ImgHead1[3])+" "+AnsiString(ImgHead1[4]);
debug_print "head2     " + AnsiString(ImgHead2[0])+" "+AnsiString(ImgHead2[1])+" "+AnsiString(ImgHead2[2])+" "+AnsiString(ImgHead2[3])+" "+AnsiString(ImgHead2[4]);



Button32->Caption =AnsiString(read1)+" "+AnsiString(read2)+" " +AnsiString(read3)+" "+AnsiString(read4)+" "+AnsiString(read5)+" " +AnsiString(read6);



IplImage *img = cvCreateImageHeader(cvSize(1280,960),8,1);
img->imageData = ImgDataA;

cvNamedWindow("show",0);
cvShowImage("show",img);
cvWaitKey();
cvDestroyWindow("show");
cvReleaseImage(&img);

}




As we said before, 1280*960 is the multiple of 512. So you can read with this two way. In windows the USB one read can be a big value so both of the following codes are ok.

read1 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,8000);       
read2 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960+5,ImgDataA,8000);


or

read1 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,8000);
read2 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,8000);
read3 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,8000);


The first read will meet the pktend and it will return only five byte.
 






A better code that wait for long exposure time almost end then read usb

Code: [Select]

struct CameraStatu{


unsigned char firmware_year;
unsigned char firmware_month;
unsigned char firmware_day;

int data_in_ddr;
unsigned int expTime;
unsigned int expTime_toend;

unsigned char seriesNumber[16];
unsigned char cmosfreq;

unsigned char temp_unit;

short current_temp_degree;
short target_temp_degree;
unsigned short current_temp_adu;
unsigned short target_temp_adu;

unsigned char pwm;
unsigned char isAuto;

unsigned char camera_submodel;
unsigned char sensor_type;

unsigned short imageX;
unsigned short imageY;

unsigned char is16bit;
unsigned char usbspeed;



unsigned char uart[8];

unsigned short reg300c;
unsigned int   actual_expTime;
};

CameraStatu cs;




CameraStatu readCameraStatu(CameraStatu *cs){
unsigned short index, value;
unsigned char data[64];

unsigned int length = 64;
index = 0;

QHYCCDVendRequestRead(g_hCam, 0xd2, 0, index, length, data);

cs->cmosfreq        =data[0];

cs->expTime_toend=    data[1]*256*256*256+data[2]*256*256+data[3]*256+data[4];
cs->expTime        =  data[5]*256*256*256+data[6]*256*256+data[7]*256+data[8];

cs->firmware_year  =data[9];
cs->firmware_month =data[10];
cs->firmware_day   =data[11];

cs->temp_unit=data[12];
cs->current_temp_degree=data[13]*256+data[14];
cs->target_temp_degree =data[15]*256+data[16];


cs->pwm=data[17];
cs->isAuto=data[18];

cs->data_in_ddr=    data[19]*256*256+data[20]*256+data[21];


cs->current_temp_adu=data[22]*256+data[23];
cs->target_temp_adu =data[24]*256+data[25];


cs->camera_submodel=data[46];
cs->sensor_type=data[47];


cs->imageX=data[28]*256+data[29];
cs->imageY=data[30]*256+data[31];

cs->is16bit=data[32];
cs->usbspeed=data[33];

for(int i=0;i<16;i++){
cs->seriesNumber[i]=data[48+i];
}

for(int i=0;i<8;i++){
cs->uart[i]=data[38+i];
}
}



unsigned char ImgDataA[1280*960];
void __fastcall TForm1::Button32Click(TObject *Sender)
{
int read1,read2,read3,read4,read5,read6;


unsigned char ImgHead1[5];
unsigned char ImgHead2[5];


readCameraStatu(&cs);


CCC_A6(0);


if(cs.expTime>2000000){

  readCameraStatu(&cs);
  while(cs.expTime_toend >2000000){
   readCameraStatu(&cs);
   debug_print AnsiString(cs.expTime_toend);
   Sleep(500);
   Application->ProcessMessages();
  }

}


  debug_print AnsiString(cs.expTime);
  debug_print AnsiString(cs.expTime_toend);
  debug_print AnsiString(cs.imageX);
  debug_print AnsiString(cs.imageY);

  imgX=cs.imageX;
  imgY=cs.imageY;

  long imgBufferSize=imgX*imgY;

  debug_print AnsiString(imgBufferSize);


read1 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,3000);
memcpy(ImgHead1,ImgDataA,5);
read2 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,3000);
read3 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960,ImgDataA,3000);
memcpy(ImgHead2,ImgDataA,5);
//read4 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960*2,ImgDataA,8000);
//read5 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960*2,ImgDataA,8000);
//read6 = QHYCCDReadUSB_SYNC(g_hCam,0x82,1280*960*2,ImgDataA,8000);






debug_print "head1     " + AnsiString(ImgHead1[0])+" "+AnsiString(ImgHead1[1])+" "+AnsiString(ImgHead1[2])+" "+AnsiString(ImgHead1[3])+" "+AnsiString(ImgHead1[4]);
debug_print "head2     " + AnsiString(ImgHead2[0])+" "+AnsiString(ImgHead2[1])+" "+AnsiString(ImgHead2[2])+" "+AnsiString(ImgHead2[3])+" "+AnsiString(ImgHead2[4]);



Button32->Caption =AnsiString(read1)+" "+AnsiString(read2)+" " +AnsiString(read3)+" "+AnsiString(read4)+" "+AnsiString(read5)+" " +AnsiString(read6);



IplImage *img = cvCreateImageHeader(cvSize(imgX,imgY),8,1);
img->imageData = ImgDataA;

cvNamedWindow("show",0);
cvShowImage("show",img);
cvWaitKey();
cvDestroyWindow("show");
cvReleaseImage(&img);
« Last Edit: May 14, 2017, 12:21:59 PM by QiuHY »
Qiu Hongyun

QiuHY

  • *****
  • 5005
    • View Profile
    • Email
Re: QHY5L-II Low Level (1) USB Protocol
« Reply #7 on: June 10, 2017, 04:26:46 AM »
Hello,
          We get some feedback of the last single firmware support . There maybe a little bug in it and cause the amp light is very bright than normal when exposure >5 sec. We will check the reason and adjust it.  But the control method should be the same.

Best regards,
Qiu Hongyun
Qiu Hongyun

Re: QHY5L-II Low Level (1) USB Protocol
« Reply #8 on: March 14, 2018, 05:06:37 PM »
I'm getting the following errors when I try to load the software (above) using fxload. I'm running 17.10 ubuntu.

microcontroller type: fx3
single stage:  load on-chip memory
open RAM image /lib/firmware/qhy/QHY5LII_V20170313.HEX
Invalid file: missing CYpress signature
unable to download /lib/firmware/qhy/QHY5LII_V20170313.HEX

The command line I'm using is:

sudo /sbin/fxload -v -t fx3 -I /lib/firmware/qhy/QHY5LII_V20170313.HEX -D /dev/bus/usb/001/005

Any ideas?

Re: QHY5L-II Low Level (1) USB Protocol
« Reply #9 on: March 15, 2018, 01:34:13 AM »
Well, this worked this time:

sudo fxload -vvvvvvvv -t fx2 -s /lib/firmware/qhy/QHY5LOADER.HEX -I qhy5lii_v20170510.hex -D /dev/bus/usb/001/006

It seems to magically to have started working. I swear I tried the above line before.

Also, the QHY5LII_V20170313.hex loaded, but the camera was dead: Known good software could no longer talk to it, and software that conformed to the above spec wouldn't work either.

After I did the above, my old software (using the sdk) wouldn't work, but my new software (based on the above) does!!!

I don't care! I'm writing this all over again anyway.

Better yet, I'm recoding this in python using pyusb.

Works just fine!

I'm a happy camper!!

thx, tom.c