static int send_dreg(struct vio_driver_state *vio) { struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_TX_RING]; union { struct vio_dring_register pkt; char all[sizeof(struct vio_dring_register) + (sizeof(struct ldc_trans_cookie) * dr->ncookies)]; } u; int i; memset(&u, 0, sizeof(u)); init_tag(&u.pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_DRING_REG); u.pkt.dring_ident = 0; u.pkt.num_descr = dr->num_entries; u.pkt.descr_size = dr->entry_size; u.pkt.options = VIO_TX_DRING; u.pkt.num_cookies = dr->ncookies; viodbg(HS, "SEND DRING_REG INFO ndesc[%u] dsz[%u] opt[0x%x] " "ncookies[%u]\n", u.pkt.num_descr, u.pkt.descr_size, u.pkt.options, u.pkt.num_cookies); for (i = 0; i < dr->ncookies; i++) { u.pkt.cookies[i] = dr->cookies[i]; viodbg(HS, "DRING COOKIE(%d) [%016llx:%016llx]\n", i, (unsigned long long) u.pkt.cookies[i].cookie_addr, (unsigned long long) u.pkt.cookies[i].cookie_size); } return send_ctrl(vio, &u.pkt.tag, sizeof(u)); }
void Chatpad::set_led(unsigned int led, bool state) { if (state) { m_led_state |= led; if (led == CHATPAD_LED_PEOPLE) { send_ctrl(0x41, 0x00, 0x000b, 0x0002, NULL, 0); } else if (led == CHATPAD_LED_ORANGE) { send_ctrl(0x41, 0x00, 0x000a, 0x0002, NULL, 0); } else if (led == CHATPAD_LED_GREEN) { send_ctrl(0x41, 0x00, 0x0009, 0x0002, NULL, 0); } else if (led == CHATPAD_LED_SHIFT) { send_ctrl(0x41, 0x00, 0x0008, 0x0002, NULL, 0); } } else { m_led_state &= ~led; if (led == CHATPAD_LED_PEOPLE) { send_ctrl(0x41, 0x00, 0x0003, 0x0002, NULL, 0); } else if (led == CHATPAD_LED_ORANGE) { send_ctrl(0x41, 0x00, 0x0002, 0x0002, NULL, 0); } else if (led == CHATPAD_LED_GREEN) { send_ctrl(0x41, 0x00, 0x0001, 0x0002, NULL, 0); } else if (led == CHATPAD_LED_SHIFT) { send_ctrl(0x41, 0x00, 0x0000, 0x0002, NULL, 0); } else if (led == CHATPAD_LED_BACKLIGHT) { // backlight goes on automatically, so we only provide a switch to disable it send_ctrl(0x41, 0x00, 0x0004, 0x0002, NULL, 0); } } }
static int process_rdx_info(struct vio_driver_state *vio, struct vio_rdx *pkt) { viodbg(HS, "GOT RDX INFO\n"); pkt->tag.stype = VIO_SUBTYPE_ACK; viodbg(HS, "SEND RDX ACK\n"); if (send_ctrl(vio, &pkt->tag, sizeof(*pkt)) < 0) return handshake_failure(vio); vio->hs_state |= VIO_HS_SENT_RDX_ACK; return 0; }
static int send_rdx(struct vio_driver_state *vio) { struct vio_rdx pkt; memset(&pkt, 0, sizeof(pkt)); init_tag(&pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_RDX); viodbg(HS, "SEND RDX INFO\n"); return send_ctrl(vio, &pkt.tag, sizeof(pkt)); }
void Chatpad::keep_alive_thread() { try { // loop and send keep alives while(!m_quit_thread) { send_ctrl(0x41, 0x0, 0x1f, 0x02, NULL, 0); log_debug("0x1f"); sleep(1); send_ctrl(0x41, 0x0, 0x1e, 0x02, NULL, 0); log_debug("0x1e"); sleep(1); } } catch(const std::exception& err) { log_error(err.what()); } }
bool Chatpad::on_timeout() { //m_timeout_id = -1; switch(m_init_state) { case kStateInit_1e: case kStateKeepAlive_1e: send_ctrl(0x41, 0x0, 0x1f, 0x02, NULL, 0, &Chatpad::on_control_wrap, this); return false; case kStateInit_1f: case kStateKeepAlive_1f: send_ctrl(0x41, 0x0, 0x1e, 0x02, NULL, 0, &Chatpad::on_control_wrap, this); return false; default: assert(!"invalid state"); break; } }
static int send_version(struct vio_driver_state *vio, u16 major, u16 minor) { struct vio_ver_info pkt; vio->_local_sid = (u32) sched_clock(); memset(&pkt, 0, sizeof(pkt)); init_tag(&pkt.tag, VIO_TYPE_CTRL, VIO_SUBTYPE_INFO, VIO_VER_INFO); pkt.major = major; pkt.minor = minor; pkt.dev_class = vio->dev_class; viodbg(HS, "SEND VERSION INFO maj[%u] min[%u] devclass[%u]\n", major, minor, vio->dev_class); return send_ctrl(vio, &pkt.tag, sizeof(pkt)); }
static int process_dreg_info(struct vio_driver_state *vio, struct vio_dring_register *pkt) { struct vio_dring_state *dr; int i, len; viodbg(HS, "GOT DRING_REG INFO ident[%llx] " "ndesc[%u] dsz[%u] opt[0x%x] ncookies[%u]\n", (unsigned long long) pkt->dring_ident, pkt->num_descr, pkt->descr_size, pkt->options, pkt->num_cookies); if (!(vio->dr_state & VIO_DR_STATE_RXREQ)) goto send_nack; if (vio->dr_state & VIO_DR_STATE_RXREG) goto send_nack; BUG_ON(vio->desc_buf); vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); if (!vio->desc_buf) goto send_nack; vio->desc_buf_len = pkt->descr_size; dr = &vio->drings[VIO_DRIVER_RX_RING]; dr->num_entries = pkt->num_descr; dr->entry_size = pkt->descr_size; dr->ncookies = pkt->num_cookies; for (i = 0; i < dr->ncookies; i++) { dr->cookies[i] = pkt->cookies[i]; viodbg(HS, "DRING COOKIE(%d) [%016llx:%016llx]\n", i, (unsigned long long) pkt->cookies[i].cookie_addr, (unsigned long long) pkt->cookies[i].cookie_size); } pkt->tag.stype = VIO_SUBTYPE_ACK; pkt->dring_ident = ++dr->ident; viodbg(HS, "SEND DRING_REG ACK ident[%llx]\n", (unsigned long long) pkt->dring_ident); len = (sizeof(*pkt) + (dr->ncookies * sizeof(struct ldc_trans_cookie))); if (send_ctrl(vio, &pkt->tag, len) < 0) goto send_nack; vio->dr_state |= VIO_DR_STATE_RXREG; return 0; send_nack: pkt->tag.stype = VIO_SUBTYPE_NACK; viodbg(HS, "SEND DRING_REG NACK\n"); (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); return handshake_failure(vio); }
static int process_ver_info(struct vio_driver_state *vio, struct vio_ver_info *pkt) { struct vio_version *vap; int err; viodbg(HS, "GOT VERSION INFO maj[%u] min[%u] devclass[%u]\n", pkt->major, pkt->minor, pkt->dev_class); if (vio->hs_state != VIO_HS_INVALID) { /* XXX Perhaps invoke start_handshake? XXX */ memset(&vio->ver, 0, sizeof(vio->ver)); vio->hs_state = VIO_HS_INVALID; } vap = find_by_major(vio, pkt->major); vio->_peer_sid = pkt->tag.sid; if (!vap) { pkt->tag.stype = VIO_SUBTYPE_NACK; pkt->major = 0; pkt->minor = 0; viodbg(HS, "SEND VERSION NACK maj[0] min[0]\n"); err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); } else if (vap->major != pkt->major) { pkt->tag.stype = VIO_SUBTYPE_NACK; pkt->major = vap->major; pkt->minor = vap->minor; viodbg(HS, "SEND VERSION NACK maj[%u] min[%u]\n", pkt->major, pkt->minor); err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); } else { struct vio_version ver = { .major = pkt->major, .minor = pkt->minor, }; if (ver.minor > vap->minor) ver.minor = vap->minor; pkt->minor = ver.minor; pkt->tag.stype = VIO_SUBTYPE_ACK; viodbg(HS, "SEND VERSION ACK maj[%u] min[%u]\n", pkt->major, pkt->minor); err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); if (err > 0) { vio->ver = ver; vio->hs_state = VIO_HS_GOTVERS; } } if (err < 0) return handshake_failure(vio); return 0; } static int process_ver_ack(struct vio_driver_state *vio, struct vio_ver_info *pkt) { viodbg(HS, "GOT VERSION ACK maj[%u] min[%u] devclass[%u]\n", pkt->major, pkt->minor, pkt->dev_class); if (vio->hs_state & VIO_HS_GOTVERS) { if (vio->ver.major != pkt->major || vio->ver.minor != pkt->minor) { pkt->tag.stype = VIO_SUBTYPE_NACK; (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); return handshake_failure(vio); } } else { vio->ver.major = pkt->major; vio->ver.minor = pkt->minor; vio->hs_state = VIO_HS_GOTVERS; } switch (vio->dev_class) { case VDEV_NETWORK: case VDEV_DISK: if (send_attr(vio) < 0) return handshake_failure(vio); break; default: break; } return 0; }
void Chatpad::send_command() { //log_tmp("send_command: " << m_init_state); // default init code for m_bcdDevice == 0x0110 uint8_t code[2] = { 0x01, 0x02 }; if (m_bcdDevice == 0x0114) { code[0] = 0x09; code[1] = 0x00; } switch(m_init_state) { case kStateInit1: send_ctrl(0x40, 0xa9, 0xa30c, 0x4423, NULL, 0, &Chatpad::on_control_wrap, this); break; case kStateInit2: send_ctrl(0x40, 0xa9, 0x2344, 0x7f03, NULL, 0, &Chatpad::on_control_wrap, this); break; case kStateInit3: send_ctrl(0x40, 0xa9, 0x5839, 0x6832, NULL, 0, &Chatpad::on_control_wrap, this); break; case kStateInit4: send_ctrl(0xc0, 0xa1, 0x0000, 0xe416, code, 2, &Chatpad::on_control_wrap, this); break; case kStateInit5: send_ctrl(0x40, 0xa1, 0x0000, 0xe416, code, 2, &Chatpad::on_control_wrap, this); break; case kStateInit6: send_ctrl(0xc0, 0xa1, 0x0000, 0xe416, code, 2, &Chatpad::on_control_wrap, this); break; case kStateInit_1e: send_timeout(1000); break; case kStateInit_1f: send_timeout(1000); break; case kStateInit_1b: send_ctrl(0x41, 0x0, 0x1b, 0x02, NULL, 0, &Chatpad::on_control_wrap, this); break; case kStateKeepAlive_1e: send_timeout(1000); break; case kStateKeepAlive_1f: send_timeout(1000); break; default: assert(!"unknown state"); break; } }
static void stop(struct asill_s *A) { pthread_mutex_lock(&A->cmd_lock); send_ctrl(A, 0xaa); pthread_mutex_unlock(&A->cmd_lock); }
static void init(struct asill_s *A) { float T55, T70; pthread_mutex_lock(&A->cmd_lock); send_ctrl(A, 0xa4); send_ctrl(A, 0xab); send_ctrl(A, 0xaa); set_reg(A, MT9M034_RESET_REGISTER, 0x0001); sleep_ms(A, 101); set_reg(A, MT9M034_SEQ_CTRL_PORT, 0x8000); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0225); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x5050); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2d26); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0828); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0d17); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0926); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0028); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0526); set_reg(A, MT9M034_SEQ_DATA_PORT, 0xa728); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0725); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x8080); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2917); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0525); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0040); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2702); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1616); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2706); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1736); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x26a6); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1703); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x26a4); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x171f); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2805); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2620); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2804); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2520); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2027); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0017); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1e25); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0020); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2117); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1028); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x051b); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1703); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2706); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1703); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1747); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2660); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x17ae); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2500); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x9027); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0026); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1828); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x002e); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2a28); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x081e); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0831); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1440); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x4014); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2020); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1410); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1034); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1400); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1014); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0020); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1400); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x4013); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1802); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1470); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x7004); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1470); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x7003); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1470); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x7017); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2002); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1400); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2002); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1400); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x5004); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1400); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2004); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x1400); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x5022); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0314); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0020); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0314); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x0050); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2c2c); set_reg(A, MT9M034_SEQ_DATA_PORT, 0x2c2c); set_reg(A, MT9M034_ERS_PROG_START_ADDR, 0x0000); set_reg(A, MT9M034_RESET_REGISTER, 0x10d8); set_reg(A, MT9M034_MODE_CTRL, 0x0029); set_reg(A, MT9M034_DATA_PEDESTAL, 0x0000); set_reg(A, MT9M034_DAC_LD_14_15, 0x0f03); set_reg(A, MT9M034_DAC_LD_18_19, 0xc005); set_reg(A, MT9M034_DAC_LD_12_13, 0x09ef); set_reg(A, MT9M034_DAC_LD_22_23, 0xa46b); set_reg(A, MT9M034_DAC_LD_20_21, 0x047d); set_reg(A, MT9M034_DAC_LD_16_17, 0x0070); set_reg(A, MT9M034_DARK_CONTROL, 0x0404); set_reg(A, MT9M034_DAC_LD_26_27, 0x8303); // note: was set_reg(A, MT9M034_DAC_LD_24_25, 0xd308); // in driver, but DS says put low conversion gain for // column correction calibration. set_reg(A, MT9M034_DAC_LD_24_25, 0xd008); set_reg(A, MT9M034_DAC_LD_10_11, 0x00bd); set_reg(A, MT9M034_DAC_LD_26_27, 0x8303); set_reg(A, MT9M034_ADC_BITS_6_7, 0x6372); set_reg(A, MT9M034_ADC_BITS_4_5, 0x7253); set_reg(A, MT9M034_ADC_BITS_2_3, 0x5470); set_reg(A, MT9M034_ADC_CONFIG1, 0xc4cc); set_reg(A, MT9M034_ADC_CONFIG2, 0x8050); set_reg(A, MT9M034_DIGITAL_TEST, 0x5300); set_reg(A, MT9M034_COLUMN_CORRECTION, 0xe007); set_reg(A, MT9M034_DIGITAL_CTRL, 0x0008); set_reg(A, MT9M034_RESET_REGISTER, 0x10dc); set_reg(A, MT9M034_RESET_REGISTER, 0x10d8); set_reg(A, MT9M034_COARSE_INTEGRATION_TIME, 0x0fff); set_reg(A, MT9M034_DIGITAL_TEST, 0x5300); sleep_ms(A, 101); set_reg(A, MT9M034_EMBEDDED_DATA_CTRL, 0x1802); set_reg(A, 0x30b4, 0x0011); set_reg(A, MT9M034_AE_CTRL_REG, 0x0000); set_reg(A, MT9M034_READ_MODE, 0x4000); set_reg(A, MT9M034_DIGITAL_TEST, 0x1330); set_reg(A, MT9M034_GLOBAL_GAIN, 0x0024); sleep_ms(A, 19); set_reg(A, MT9M034_RED_GAIN, 0x0022); set_reg(A, MT9M034_BLUE_GAIN, 0x003e); set_reg(A, MT9M034_DATA_PEDESTAL, 0x0000); set_reg(A, MT9M034_LINE_LENGTH_PCK, 0x056e); set_reg(A, MT9M034_COARSE_INTEGRATION_TIME, 0x0473); #if 0 /* should be gain = 50 */ set_reg(A, MT9M034_DAC_LD_24_25, 0xd308); set_reg(A, MT9M034_GLOBAL_GAIN, 0x0024); set_reg(A, MT9M034_DIGITAL_TEST, 0x1330); #else /* unity gain digital, minum analog*/ set_reg(A, MT9M034_DIGITAL_TEST, 0x1300); set_reg(A, MT9M034_DAC_LD_24_25, 0xd008); set_reg(A, MT9M034_RED_GAIN, 0x0020); set_reg(A, MT9M034_BLUE_GAIN, 0x0020); set_reg(A, MT9M034_GREEN1_GAIN, 0x0020); set_reg(A, MT9M034_GREEN2_GAIN, 0x0020); set_reg(A, MT9M034_GLOBAL_GAIN, 0x0020); #endif /* read temperature coefficents */ T70 = get_reg_r(A, 0x30c6) & 0x7ff; T55 = get_reg_r(A, 0x30c8) & 0x7ff; A->Tk = (70.0 - 55.0) / (T70 - T55); A->T0 = 55.0 - A->Tk * T55; /* default flip for compatibility with yaaca zwo.c */ set_reg(A, MT9M034_READ_MODE, 0x0000); setup_frame(A); /* start capture */ send_ctrl(A, 0xaa); send_ctrl(A, 0xaf); sleep_ms(A, 100); send_ctrl(A, 0xa9); pthread_mutex_unlock(&A->cmd_lock); }
static int setup_frame(struct asill_s *A) { #define MAX_COARSE 0x2000 uint16_t tot_w = 1600; uint16_t tot_h = A->height + H_EXCESS; uint16_t coarse, fine; double pclk = 48000000.0 * M_PLL_mul[A->pclk] / (N_pre_div[A->pclk] * P1_sys_div[A->pclk] * P2_clk_div[A->pclk]); double line_us = (tot_w / pclk) * 1000000.0; double fine_real; pr_debug("%s pclk %f exp %u line_us %f\n", __FUNCTION__, pclk, A->exposure_us, line_us); pr_debug("%s %dx%d:%d\n", __FUNCTION__, A->width, A->height, A->bin); #if 1 if (A->exposure_us > 100000) { tot_w = 0x2fff; line_us = (tot_w / pclk) * 1000000.0; } coarse = A->exposure_us / line_us; #else while( (coarse = A->exposure_us / line_us) > MAX_COARSE) { tot_w *= 2; line_us = (tot_w / pclk) * 1000000.0; pr_debug("%s tot_w %d coarse %d line_us %f\n", __FUNCTION__, tot_w, coarse, line_us); } #endif pr_debug("%s finale: tot_w %d coarse %d line_us %f\n", __FUNCTION__, tot_w, coarse, line_us); fine_real = A->exposure_us *pclk / 1000000.0 - tot_w * coarse; pr_debug("%s fine: %f\n", __FUNCTION__, fine_real); // note: if fine_real is 0 we have similar brightness (if we set the same gain of course!) to ZWO's libASICamera fine_real = 0; fine = fine_real; A->exposure_real_us = coarse * line_us + fine_real / (pclk / 1000000.0); pr_debug("%s real exp us: %u (fine %d)\n", __FUNCTION__, A->exposure_real_us, fine); set_reg(A, MT9M034_FINE_INT_TIME, fine); set_reg(A, MT9M034_COARSE_INTEGRATION_TIME, coarse); set_reg(A, MT9M034_RESET_REGISTER, 0x10da); sleep_ms(A, 101); set_reg(A, MT9M034_VT_PIX_CLK_DIV, P2_clk_div[A->pclk]); set_reg(A, MT9M034_VT_SYS_CLK_DIV, P1_sys_div[A->pclk]); set_reg(A, MT9M034_PRE_PLL_CLK_DIV, N_pre_div[A->pclk]); set_reg(A, MT9M034_PLL_MULTIPLIER, M_PLL_mul[A->pclk]); sleep_ms(A, 11); set_reg(A, MT9M034_RESET_REGISTER, 0x10dc); sleep_ms(A, 201); send_ctrl(A, A->fmt == ASILL_FMT_RAW8 ? 0xab : 0xac); set_reg(A, MT9M034_DIGITAL_BINNING, A->bin == 2 ? 0x0022 : 0x0000); set_reg(A, MT9M034_Y_ADDR_START, 0x0002 + A->start_y); set_reg(A, MT9M034_X_ADDR_START, A->start_x); set_reg(A, MT9M034_FRAME_LENGTH_LINES, tot_h); set_reg(A, MT9M034_Y_ADDR_END, 0x0002 + A->start_y + A->height - 1); set_reg(A, MT9M034_X_ADDR_END, A->start_x + A->width - 1); set_reg(A, MT9M034_DIGITAL_BINNING, A->bin == 2 ? 0x0022 : 0x0000); set_reg(A, 0x306e, 0x9200); //set_reg(A, 0x306e, 0x9200 | (A->is_color ? 0x10 : 0)); set_reg(A, MT9M034_LINE_LENGTH_PCK, tot_w); set_reg(A, MT9M034_COARSE_INTEGRATION_TIME, coarse); set_reg(A, MT9M034_COARSE_INTEGRATION_TIME, coarse); #if 0 restore_rnc(A); #endif calc_min_max_exp(A); return 0; }