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 {
00030 open(devid);
00031 setDatarate(Datarate_2MPS);
00032 setChannel(2);
00033 setContCarrier(false);
00034 setAddress(0xE7E7E7E7E7);
00035 setPower(Power_0DBM);
00036 setArc(3);
00037 setArdBytes(32);
00038 }
00039
00040 Crazyradio::~Crazyradio()
00041 {
00042 }
00043
00044 uint32_t Crazyradio::numDevices()
00045 {
00046 return USBDevice::numDevices(0x1915, 0x7777);
00047 }
00048
00049 void Crazyradio::setChannel(uint8_t channel)
00050 {
00051 sendVendorSetup(SET_RADIO_CHANNEL, channel, 0, NULL, 0);
00052 m_channel = channel;
00053 }
00054
00055 void Crazyradio::setAddress(uint64_t address)
00056 {
00057 unsigned char a[5];
00058 a[4] = (address >> 0) & 0xFF;
00059 a[3] = (address >> 8) & 0xFF;
00060 a[2] = (address >> 16) & 0xFF;
00061 a[1] = (address >> 24) & 0xFF;
00062 a[0] = (address >> 32) & 0xFF;
00063
00064
00065
00066
00067 int status = libusb_control_transfer(
00068 m_handle,
00069 LIBUSB_REQUEST_TYPE_VENDOR,
00070 SET_RADIO_ADDRESS,
00071 0,
00072 0,
00073 a,
00074 5,
00075 1000);
00076
00077
00078
00079 m_address = address;
00080 }
00081
00082 void Crazyradio::setDatarate(Datarate datarate)
00083 {
00084 sendVendorSetup(SET_DATA_RATE, datarate, 0, NULL, 0);
00085 m_datarate = datarate;
00086 }
00087
00088 void Crazyradio::setPower(Power power)
00089 {
00090 sendVendorSetup(SET_RADIO_POWER, power, 0, NULL, 0);
00091 }
00092
00093 void Crazyradio::setArc(uint8_t arc)
00094 {
00095 sendVendorSetup(SET_RADIO_ARC, arc, 0, NULL, 0);
00096 }
00097
00098 void Crazyradio::setArdTime(uint8_t us)
00099 {
00100
00101
00102
00103
00104
00105
00106
00107
00108 int t = (us / 250) - 1;
00109 if (t < 0) {
00110 t = 0;
00111 }
00112 if (t > 0xF) {
00113 t = 0xF;
00114 }
00115 sendVendorSetup(SET_RADIO_ARD, t, 0, NULL, 0);
00116 }
00117
00118 void Crazyradio::setArdBytes(uint8_t nbytes)
00119 {
00120 sendVendorSetup(SET_RADIO_ARD, 0x80 | nbytes, 0, NULL, 0);
00121 }
00122
00123 void Crazyradio::setAckEnable(bool enable)
00124 {
00125 sendVendorSetup(ACK_ENABLE, enable, 0, NULL, 0);
00126 }
00127
00128 void Crazyradio::setContCarrier(bool active)
00129 {
00130 sendVendorSetup(SET_CONT_CARRIER, active, 0, NULL, 0);
00131 }
00132
00133 void Crazyradio::sendPacket(
00134 const uint8_t* data,
00135 uint32_t length,
00136 Ack& result)
00137 {
00138 int status;
00139 int transferred;
00140
00141 if (!m_handle) {
00142 throw std::runtime_error("No valid device handle!");
00143 }
00144
00145
00146 status = libusb_bulk_transfer(
00147 m_handle,
00148 (0x01 | LIBUSB_ENDPOINT_OUT),
00149 (uint8_t*)data,
00150 length,
00151 &transferred,
00152 1000);
00153 if (status != LIBUSB_SUCCESS) {
00154 throw std::runtime_error(libusb_error_name(status));
00155 }
00156 if (length != transferred) {
00157 std::stringstream sstr;
00158 sstr << "Did transfer " << transferred << " but " << length << " was requested!";
00159 throw std::runtime_error(sstr.str());
00160 }
00161
00162
00163 result.ack = false;
00164 result.size = 0;
00165 status = libusb_bulk_transfer(
00166 m_handle,
00167 (0x81 | LIBUSB_ENDPOINT_IN),
00168 (unsigned char*)&result,
00169 sizeof(result) - 1,
00170 &transferred,
00171 1000);
00172 if (status != LIBUSB_SUCCESS) {
00173 throw std::runtime_error(libusb_error_name(status));
00174 }
00175
00176 result.size = transferred - 1;
00177 }
00178
00179 void Crazyradio::sendPacketNoAck(
00180 const uint8_t* data,
00181 uint32_t length)
00182 {
00183 int status;
00184 int transferred;
00185
00186 if (!m_handle) {
00187 throw std::runtime_error("No valid device handle!");
00188 }
00189
00190
00191 status = libusb_bulk_transfer(
00192 m_handle,
00193 (0x01 | LIBUSB_ENDPOINT_OUT),
00194 (uint8_t*)data,
00195 length,
00196 &transferred,
00197 1000);
00198 if (status != LIBUSB_SUCCESS) {
00199 throw std::runtime_error(libusb_error_name(status));
00200 }
00201 if (length != transferred) {
00202 std::stringstream sstr;
00203 sstr << "Did transfer " << transferred << " but " << length << " was requested!";
00204 throw std::runtime_error(sstr.str());
00205 }
00206 }