USBUART
A library for reading/wring data via USB-UART adapters
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules
ch34x.cpp
Go to the documentation of this file.
1 
5 /* This file is part of USBUART Library. http://usbuart.info/
6  *
7  * Copyright (C) 2016 Eugene Hutorny <eugene@hutorny.in.ua>
8  *
9  * The USBUART Library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License v2
11  * as published by the Free Software Foundation;
12  *
13  * The USBUART Library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  * See the GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with the USBUART Library; if not, see
20  * <http://www.gnu.org/licenses/gpl-2.0.html>.
21  */
22 #include <libusb.h>
23 #include "usbuart.hpp"
24 
25 /******************************************************************************/
26 namespace usbuart {
27 
28 //TODO sendbreak
29 
30 class ch34x : public generic {
31 public:
32  struct baudtable {
33  unsigned baud;
34  uint16_t div1;
35  uint16_t div2;
36  };
37 
38  static const struct interface _ifc;
39  ~ch34x() noexcept {
40 // libusb_release_interface(dev,ifc.number);
41  }
42 
43  void setbaudrate(baudrate_t baudrate) const throw(error_t) {
44  static const struct baudtable table[] = {
45  { 2400, 0xd901, 0x0038},
46  { 4800, 0x6402, 0x001f},
47  { 9600, 0xb202, 0x0013},
48  { 19200, 0xd902, 0x000d},
49  { 38400, 0x6403, 0x000a},
50  { 57600, 0x9803, 0x0010},
51  {115200, 0xcc03, 0x0008}
52  };
53 
54  for (int i = 0; i < countof(table); ++i) {
55  if( table[i].baud == baudrate ) {
56  write_cv(0x9a, 0x1312, table[i].div1);
57  write_cv(0x9a, 0x0f2c, table[i].div2);
58  return;
59  }
60  }
62  }
63 
64  inline void check_v(uint8_t req, uint16_t expected) const throw(error_t) {
65  uint16_t check;
66  read_cv(req, 0, check);
67  if( check != expected ) {
68  log.i(__,"probe mismatch on %2x: got %4x expected %4x",
69  req, check, expected);
71  }
72  }
73 
74  void probe() const throw(error_t) {
75 // check_v(0x5f, 0x0027); /* read_cv 0x5f expect two bytes 0x27 0x00 */
76  write_cv(0xa1, 0, 0);
77 // check_v(0x95, 0x0056); /* read_cv 0x95 expect two bytes 0x56 0x00 */
78  write_cv(0x9a, 0x2518, 0x0050);
79  write_cv(0xa1, 0x501f, 0xd90a);
80  }
81 
82  void setup(const eia_tia_232_info& info) const throw(error_t) {
83  setbaudrate(info.baudrate);
84  setflowcontrol(info.flowcontrol);
85  reset();
87  }
88  void read_callback(libusb_transfer*, size_t& pos) noexcept {
89  pos = 0;
90  }
91 
92  void reset() const throw(error_t) {
93  /* no documented sequence for resetting the chip */
94  }
95 
96 private:
97  inline ch34x(libusb_device_handle* d, uint8_t ifnum) throw(error_t)
98  : generic(d, _ifc, ifnum) {}
99  void setflowcontrol(flow_control_t fc) const throw(error_t) {
100  write_cv(0xa4, (
101  fc == rts_cts ? ~(1 << 6) :
102  fc == dtr_dsr ? ~(1 << 5) : 0xFF),0);
103  }
104  static class factory : driver::factory {
105  void probe(libusb_device_handle*, uint8_t) const throw(error_t);
106  driver* create(libusb_device_handle*, uint8_t) const throw(error_t);
107  } _factory;
108 };
109 
110 const struct interface ch34x::_ifc = {
111  0x2|LIBUSB_ENDPOINT_IN,
112  0x2|LIBUSB_ENDPOINT_OUT,
113  256
114 };
115 
116 ch34x::factory ch34x::_factory;
117 
118 
119 void ch34x::factory::probe(libusb_device_handle* handle, uint8_t ifc)
120  const throw(error_t) {
121  ch34x driver(handle, ifc);
122  driver.probe();
123 }
124 
125 driver* ch34x::factory::create(libusb_device_handle* handle, uint8_t ifc)
126  const throw(error_t) {
127  static constexpr const uint32_t table[] = {
128  devid32(0x4348, 0x5523),
129  devid32(0x1a86, 0x7523),
130  devid32(0x1a86, 0x5523),
131  };
132 
133  device_id did = devid(handle);
134  uint32_t id = devid32(did);
135  if( ! id ) return nullptr;
136  bool found = false;
137 
138  for(auto&& i : table) {
139  if( (found = (i == id)) )
140  break;
141  }
142  if( ! found ) return nullptr;
143  log.i(__,"probing %s for %04x:%04x", "ch34x", did.vid, did.pid);
144  try { probe(handle, ifc); }
145  catch(error_t err) {
146  log.i(__,"probe %s error %d for %04x:%04x",
147  "ch34x", +err, did.vid, did.pid);
148  throw err;
149  }
150  return new ch34x(handle, ifc);
151 }
152 } /* namespace usbuart */
uint32_t baudrate_t
Baud rate data type.
Definition: usbuart.h:35
enum usbuart::flow_control_enum flow_control_t
Flow control enum.
implementation header USBUART Library
void setup(const eia_tia_232_info &) const
setup protocol on the hardware level
Definition: usbuart.hpp:143
USBUART namespace.
Definition: usbuart.h:29
device returned unexpected value while probing
error_t
API Error codes.
Definition: usbuart.h:177
unsupported baud rate