00001 #include "Crazyradio.h"
00002
00003 #include <sstream>
00004 #include <stdexcept>
00005
00006 #include <libusb-1.0/libusb.h>
00007
00008 enum
00009 {
00010 SET_RADIO_CHANNEL = 0x01,
00011 SET_RADIO_ADDRESS = 0x02,
00012 SET_DATA_RATE = 0x03,
00013 SET_RADIO_POWER = 0x04,
00014 SET_RADIO_ARD = 0x05,
00015 SET_RADIO_ARC = 0x06,
00016 ACK_ENABLE = 0x10,
00017 SET_CONT_CARRIER = 0x20,
00018 SCANN_CHANNELS = 0x21,
00019 LAUNCH_BOOTLOADER = 0xFF,
00020 };
00021
00022 Crazyradio::Crazyradio(
00023 uint32_t devid)
00024 : ITransport()
00025 , USBDevice(0x1915, 0x7777)
00026 , m_channel(0)
00027 , m_address(0)
00028 , m_datarate(Datarate_250KPS)
00029 , m_ackEnable(true)
00030 {
00031 open(devid);
00032 setDatarate(Datarate_2MPS);
00033 setChannel(2);
00034 setContCarrier(false);
00035 setAddress(0xE7E7E7E7E7);
00036 setPower(Power_0DBM);
00037 setArc(3);
00038 setArdBytes(32);
00039 setAckEnable(true);
00040 }
00041
00042 Crazyradio::~Crazyradio()
00043 {
00044 }
00045
00046 uint32_t Crazyradio::numDevices()
00047 {
00048 return USBDevice::numDevices(0x1915, 0x7777);
00049 }
00050
00051 void Crazyradio::setChannel(uint8_t channel)
00052 {
00053 sendVendorSetup(SET_RADIO_CHANNEL, channel, 0, NULL, 0);
00054 m_channel = channel;
00055 }
00056
00057 void Crazyradio::setAddress(uint64_t address)
00058 {
00059 unsigned char a[5];
00060 a[4] = (address >> 0) & 0xFF;
00061 a[3] = (address >> 8) & 0xFF;
00062 a[2] = (address >> 16) & 0xFF;
00063 a[1] = (address >> 24) & 0xFF;
00064 a[0] = (address >> 32) & 0xFF;
00065
00066
00067
00068
00069 libusb_control_transfer(
00070 m_handle,
00071 LIBUSB_REQUEST_TYPE_VENDOR,
00072 SET_RADIO_ADDRESS,
00073 0,
00074 0,
00075 a,
00076 5,
00077 1000);
00078
00079
00080
00081 m_address = address;
00082 }
00083
00084 void Crazyradio::setDatarate(Datarate datarate)
00085 {
00086 sendVendorSetup(SET_DATA_RATE, datarate, 0, NULL, 0);
00087 m_datarate = datarate;
00088 }
00089
00090 void Crazyradio::setPower(Power power)
00091 {
00092 sendVendorSetup(SET_RADIO_POWER, power, 0, NULL, 0);
00093 }
00094
00095 void Crazyradio::setArc(uint8_t arc)
00096 {
00097 sendVendorSetup(SET_RADIO_ARC, arc, 0, NULL, 0);
00098 }
00099
00100 void Crazyradio::setArdTime(uint8_t us)
00101 {
00102
00103
00104
00105
00106
00107
00108
00109
00110 int t = (us / 250) - 1;
00111 if (t < 0) {
00112 t = 0;
00113 }
00114 if (t > 0xF) {
00115 t = 0xF;
00116 }
00117 sendVendorSetup(SET_RADIO_ARD, t, 0, NULL, 0);
00118 }
00119
00120 void Crazyradio::setArdBytes(uint8_t nbytes)
00121 {
00122 sendVendorSetup(SET_RADIO_ARD, 0x80 | nbytes, 0, NULL, 0);
00123 }
00124
00125 void Crazyradio::setAckEnable(bool enable)
00126 {
00127 sendVendorSetup(ACK_ENABLE, enable, 0, NULL, 0);
00128 m_ackEnable = enable;
00129 }
00130
00131 void Crazyradio::setContCarrier(bool active)
00132 {
00133 sendVendorSetup(SET_CONT_CARRIER, active, 0, NULL, 0);
00134 }
00135
00136 void Crazyradio::sendPacket(
00137 const uint8_t* data,
00138 uint32_t length,
00139 Ack& result)
00140 {
00141 result.ack = false;
00142 result.size = 0;
00143
00144 int status;
00145 int transferred;
00146
00147 if (!m_handle) {
00148 throw std::runtime_error("No valid device handle!");
00149 }
00150
00151 if (m_enableLogging) {
00152 logPacket(data, length);
00153 }
00154
00155
00156 status = libusb_bulk_transfer(
00157 m_handle,
00158 (0x01 | LIBUSB_ENDPOINT_OUT),
00159 (uint8_t*)data,
00160 length,
00161 &transferred,
00162 100);
00163
00164
00165
00166 if (status != LIBUSB_SUCCESS) {
00167 throw std::runtime_error(libusb_error_name(status));
00168 }
00169 if (length != (uint32_t)transferred) {
00170 std::stringstream sstr;
00171 sstr << "Did transfer " << transferred << " but " << length << " was requested!";
00172 throw std::runtime_error(sstr.str());
00173 }
00174
00175
00176 status = libusb_bulk_transfer(
00177 m_handle,
00178 (0x81 | LIBUSB_ENDPOINT_IN),
00179 (unsigned char*)&result,
00180 sizeof(result) - 1,
00181 &transferred,
00182 10);
00183 if (status == LIBUSB_ERROR_TIMEOUT) {
00184 return;
00185 }
00186 if (status != LIBUSB_SUCCESS) {
00187 throw std::runtime_error(libusb_error_name(status));
00188 }
00189
00190 result.size = transferred - 1;
00191
00192 if (m_enableLogging) {
00193 logAck(result);
00194 }
00195 }
00196
00197 void Crazyradio::sendPacketNoAck(
00198 const uint8_t* data,
00199 uint32_t length)
00200 {
00201 int status;
00202 int transferred;
00203
00204 if (!m_handle) {
00205 throw std::runtime_error("No valid device handle!");
00206 }
00207
00208 if (m_enableLogging) {
00209 logPacket(data, length);
00210 }
00211
00212
00213 status = libusb_bulk_transfer(
00214 m_handle,
00215 (0x01 | LIBUSB_ENDPOINT_OUT),
00216 (uint8_t*)data,
00217 length,
00218 &transferred,
00219 100);
00220
00221
00222
00223 if (status != LIBUSB_SUCCESS) {
00224 throw std::runtime_error(libusb_error_name(status));
00225 }
00226 if (length != (uint32_t)transferred) {
00227 std::stringstream sstr;
00228 sstr << "Did transfer " << transferred << " but " << length << " was requested!";
00229 throw std::runtime_error(sstr.str());
00230 }
00231 }
00232
00233 void Crazyradio::send2PacketsNoAck(
00234 const uint8_t* data,
00235 uint32_t totalLength)
00236 {
00237 int status;
00238 int transferred;
00239
00240 if (!m_handle) {
00241 throw std::runtime_error("No valid device handle!");
00242 }
00243
00244 if (m_enableLogging) {
00245 logPacket(data, totalLength);
00246 }
00247
00248
00249 status = libusb_bulk_transfer(
00250 m_handle,
00251 (0x01 | LIBUSB_ENDPOINT_OUT),
00252 (uint8_t*)data,
00253 totalLength,
00254 &transferred,
00255 100);
00256
00257
00258
00259 if (status != LIBUSB_SUCCESS) {
00260 throw std::runtime_error(libusb_error_name(status));
00261 }
00262 if (totalLength != (uint32_t)transferred) {
00263 std::stringstream sstr;
00264 sstr << "Did transfer " << transferred << " but " << totalLength << " was requested!";
00265 throw std::runtime_error(sstr.str());
00266 }
00267 }