Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: SX127x_modtronix USBDevice_Semtech_GUI mbed
Fork of hid_test by
main.cpp
- Committer:
- dudmuck
- Date:
- 2014-04-14
- Revision:
- 0:f8bc33804548
- Child:
- 1:d25ba61cd2f3
File content as of revision 0:f8bc33804548:
#include "mbed.h"
#include "USBHID.h"
#include "sx127x.h"
// pin: 3 8 1 7 10 12 5 20 18
// mosi, miso, sclk, cs, rst, dio0, dio1, fctx, fcps
SX127x radio(PTD2, PTD3, PTD1, PTD0, PTD5, PTA13, PTD4, PTC9, PTC8);
//We declare a USBHID device. By default input and output reports are 64 bytes long.
USBHID hid(64, 64, 0x47a, 0x0b);
//USBHID (uint8_t output_report_length=64, uint8_t input_report_length=64, uint16_t vendor_id=0x1234, uint16_t product_id=0x0006, uint16_t product_release=0x0001, bool connect=true)
Serial pc(USBTX, USBRX);
//This report will contain data to be sent
HID_REPORT send_report;
HID_REPORT recv_report;
DigitalOut l1(LED1);
#define FW_VERSION "3.1.0"
#define SK_NAME "mbed"
#define HID_SK_RESET 0x00
#define HID_SK_GET_VERSION 0x01
#define HID_SK_GET_NAME 0x02
#define HID_SK_GET_PIN 0x10
#define HID_SK_SET_PIN 0x11
#define HID_SK_GET_PINS 0x14
#define HID_DEVICE_READ 0x80
#define HID_DEVICE_WRITE 0x81
#define HID_DEVICE_INIT 0x88
#define HID_DEVICE_RESET 0x89
#define HID_SK_CMD_NONE 0xFF
typedef struct sHidCommand
{
uint8_t Cmd;
uint8_t CmdOpt;
uint8_t CmdDataSize;
uint8_t *CmdData;
} tHidCommand;
typedef enum
{
SX_OK,
SX_ERROR,
SX_BUSY,
SX_EMPTY,
SX_DONE,
SX_TIMEOUT,
SX_UNSUPPORTED,
SX_WAIT,
SX_CLOSE,
SX_YES,
SX_NO,
} tReturnCodes;
#ifdef _DEBUG_
char verbose = 0;
#endif /* _DEBUG_ */
void HidDecodeCommand( uint8_t *hidReport, tHidCommand *cmd )
{
cmd->Cmd = hidReport[0];
cmd->CmdOpt = hidReport[1];
cmd->CmdDataSize = hidReport[2];
cmd->CmdData = hidReport + 3;
}
void HidEncodeCommandAns( uint8_t cmd, uint8_t stat, uint8_t dataSize, uint8_t *data )
{
send_report.data[0] = cmd;
send_report.data[1] = stat;
// TimeStamp
memset( send_report.data + 2, 0, 8 );
send_report.data[10] = dataSize;
memcpy( send_report.data + 11, ( const void* )data, dataSize );
//send_report.length = 11 + dataSize;
send_report.length = 64;
hid.send(&send_report);
}
void HidCmdProcess(void)
{
uint8_t stat = SX_OK;
uint8_t size = 0;
uint8_t dataBuffer[64];
tHidCommand cmd = { HID_SK_CMD_NONE, 0, 0, NULL };
#ifdef _DEBUG_
int i;
#endif /* _DEBUG_ */
HidDecodeCommand(recv_report.data, &cmd);
switch (cmd.Cmd) {
case HID_DEVICE_RESET:
radio.hw_reset();
break;
case HID_SK_RESET:
case HID_DEVICE_INIT:
radio.hw_reset();
#ifdef _DEBUG_
if (verbose)
printf("reset-init\r\n");
#endif /* _DEBUG_ */
radio.init(); //SX1272Init( );
// Set FSK modem ON
radio.SetLoRaOn( false ); //SX1272SetLoRaOn( false ); // Default radio setting
// Default answer settings
break;
case HID_SK_GET_VERSION:
strcpy( ( char* )dataBuffer, FW_VERSION );
size = strlen( FW_VERSION );
break;
case HID_DEVICE_READ:
// cmd.CmdData[0] = size
// cmd.CmdData[1] = address
size = cmd.CmdData[0];
radio.ReadBuffer( cmd.CmdData[1], dataBuffer, size );
#ifdef _DEBUG_
if (verbose) {
pc.printf("read %d bytes from %02x: ", size, cmd.CmdData[1]);
for (i = 0; i < size; i++)
pc.printf("%02x ", dataBuffer[i]);
pc.printf("\r\n");
}
#endif /* _DEBUG_ */
stat = SX_OK;
break;
case HID_SK_GET_PINS:
dataBuffer[0] = 0;
if (radio.dio0)
dataBuffer[0] |= 0x01;
if (radio.dio1)
dataBuffer[0] |= 0x02;
#ifdef _DEBUG_
if (verbose && dataBuffer[0] != 0)
printf("HID_SK_GET_PINS:%02x\r\n", dataBuffer[0]);
#endif /* _DEBUG_ */
/*dataBuffer[0] |= DIO1 << 1;
dataBuffer[0] |= DIO2 << 2;
dataBuffer[0] |= DIO3 << 3;
dataBuffer[0] |= DIO4 << 4;
dataBuffer[0] |= DIO5 << 5;*/
size = 1;
break;
case HID_SK_GET_PIN:
// cmd.CmdData[0] = Pin id
switch( cmd.CmdData[0] ) {
case 11: // FEM_CPS_PIN
dataBuffer[0] = radio.femcps;
#ifdef _DEBUG_
if (verbose)
printf("HID_SK_GET_PIN femcps:%02x\r\n", dataBuffer[0]);
#endif /* _DEBUG_ */
break;
case 12: // FEM_CTX_PIN
dataBuffer[0] = radio.femctx;
#ifdef _DEBUG_
if (verbose)
printf("HID_SK_GET_PIN femctx:%02x\r\n", dataBuffer[0]);
#endif /* _DEBUG_ */
break;
default:
dataBuffer[0] = 0xFF; // Signal ID error
#ifdef _DEBUG_
printf("HID_SK_GET_PIN %d\r\n", cmd.CmdData[0]);
#endif /* _DEBUG_ */
break;
} // ...switch( cmd.CmdData[0] )
break;
case HID_SK_SET_PIN:
// cmd.CmdData[0] = Pin id
// cmd.CmdData[1] = Pin state
switch( cmd.CmdData[0] ) {
case 6:
case 7:
case 8:
// ignore LEDs
break;
case 11: // FEM_CPS_PIN
radio.femcps = cmd.CmdData[1];
#ifdef _DEBUG_
if (verbose)
printf("HID_SK_SET_PIN femcps:%d\r\n", (int)radio.femcps);
#endif /* _DEBUG_ */
break;
case 12: // FEM_CTX_PIN
radio.femctx = cmd.CmdData[1];
#ifdef _DEBUG_
if (verbose)
printf("HID_SK_SET_PIN femctx:%d\r\n", (int)radio.femctx);
#endif /* _DEBUG_ */
break;
default:
stat = SX_UNSUPPORTED;
#ifdef _DEBUG_
pc.printf("HID_SK_SET_PIN %d %d\r\n", cmd.CmdData[0], cmd.CmdData[1]);
#endif /* _DEBUG_ */
break;
} // ...switch( cmd.CmdData[0] )
break;
case HID_DEVICE_WRITE:
// cmd.CmdData[0] = size
// cmd.CmdData[1] = address
// cmd.CmdData[2] = Buffer first byte
// cmd.CmdData[2+(size-1)] = Buffer last byte
radio.WriteBuffer( cmd.CmdData[1], cmd.CmdData + 2, cmd.CmdData[0] );
#ifdef _DEBUG_
if (verbose) {
pc.printf("write %d bytes to %02x: ", cmd.CmdData[0], cmd.CmdData[1]);
for (i = 0; i < cmd.CmdData[0]; i++)
pc.printf("%02x ", cmd.CmdData[2+i]);
pc.printf("\r\n");
}
#endif /* _DEBUG_ */
stat = SX_OK;
break;
case HID_SK_GET_NAME:
strcpy( ( char* )dataBuffer, SK_NAME );
size = strlen( SK_NAME );
break;
default:
pc.printf("%d: ", recv_report.length);
for(int i = 0; i < recv_report.length; i++) {
pc.printf("%02x ", recv_report.data[i]);
}
pc.printf("\r\n");
stat = SX_UNSUPPORTED;
break;
} // ...switch (cmd.Cmd)
HidEncodeCommandAns( cmd.Cmd, stat, size, dataBuffer);
}
#ifdef _DEBUG_
void printOpMode()
{
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
switch (radio.RegOpMode.bits.Mode) {
case RF_OPMODE_SLEEP: printf("[7msleep[0m"); break;
case RF_OPMODE_STANDBY: printf("[7mstby[0m"); break;
case RF_OPMODE_SYNTHESIZER_TX: printf("[33mfstx[0m"); break;
case RF_OPMODE_TRANSMITTER: printf("[31mtx[0m"); break;
case RF_OPMODE_SYNTHESIZER_RX: printf("[33mfsrx[0m"); break;
case RF_OPMODE_RECEIVER: printf("[32mrx[0m"); break;
case 6:
if (radio.RegOpMode.bits.LongRangeMode)
printf("[42mrxs[0m");
else
printf("-6-");
break; // todo: different lora/fsk
case 7:
if (radio.RegOpMode.bits.LongRangeMode)
printf("[45mcad[0m");
else
printf("-7-");
break; // todo: different lora/fsk
}
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void
printPa()
{
radio.RegPaConfig.octet = radio.read_reg(REG_PACONFIG);
if (radio.RegPaConfig.bits.PaSelect) {
float output_dBm = 17 - (15-radio.RegPaConfig.bits.OutputPower);
printf(" PABOOST OutputPower=%.1fdBm", output_dBm);
} else {
float pmax = (0.6*radio.RegPaConfig.bits.MaxPower) + 10.8;
float output_dBm = pmax - (15-radio.RegPaConfig.bits.OutputPower);
printf(" RFO pmax=%.1fdBm OutputPower=%.1fdBm", pmax, output_dBm);
}
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void /* things always present, whether lora or fsk */
common_print_status()
{
printf("version:0x%02x %.3fMHz ", radio.read_reg(REG_VERSION), radio.get_frf_MHz());
printOpMode();
printPa();
radio.RegOcp.octet = radio.read_reg(REG_OCP);
if (radio.RegOcp.bits.OcpOn) {
int imax = 0;
if (radio.RegOcp.bits.OcpTrim < 16)
imax = 45 + (5 * radio.RegOcp.bits.OcpTrim);
else if (radio.RegOcp.bits.OcpTrim < 28)
imax = -30 + (10 * radio.RegOcp.bits.OcpTrim);
else
imax = 240;
printf(" OcpOn %dmA ", imax);
} else
printf(" OcpOFF ");
printf("\r\n");
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void lora_print_dio()
{
radio.RegDioMapping2.octet = radio.read_reg(REG_DIOMAPPING2);
printf("DIO5:");
switch (radio.RegDioMapping2.bits.Dio5Mapping) {
case 0: printf("ModeReady"); break;
case 1: printf("ClkOut"); break;
case 2: printf("ClkOut"); break;
}
printf(" DIO4:");
switch (radio.RegDioMapping2.bits.Dio4Mapping) {
case 0: printf("CadDetected"); break;
case 1: printf("PllLock"); break;
case 2: printf("PllLock"); break;
}
radio.RegDioMapping1.octet = radio.read_reg(REG_DIOMAPPING1);
printf(" DIO3:");
switch (radio.RegDioMapping1.bits.Dio3Mapping) {
case 0: printf("CadDone"); break;
case 1: printf("ValidHeader"); break;
case 2: printf("PayloadCrcError"); break;
}
printf(" DIO2:");
switch (radio.RegDioMapping1.bits.Dio2Mapping) {
case 0:
case 1:
case 2:
printf("FhssChangeChannel");
break;
}
printf(" DIO1:");
switch (radio.RegDioMapping1.bits.Dio1Mapping) {
case 0: printf("RxTimeout"); break;
case 1: printf("FhssChangeChannel"); break;
case 2: printf("CadDetected"); break;
}
printf(" DIO0:");
switch (radio.RegDioMapping1.bits.Dio0Mapping) {
case 0: printf("RxDone"); break;
case 1: printf("TxDone"); break;
case 2: printf("CadDone"); break;
}
printf("\r\n");
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void
printCodingRate(bool from_rx)
{
uint8_t d = radio.getCodingRate(from_rx);
printf("CodingRate:");
switch (d) {
case 1: printf("4/5 "); break;
case 2: printf("4/6 "); break;
case 3: printf("4/7 "); break;
case 4: printf("4/8 "); break;
default:
printf("%d ", d);
break;
}
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void printHeaderMode()
{
if (radio.getHeaderMode())
printf("implicit ");
else
printf("explicit ");
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void printBw()
{
uint8_t bw = radio.getBw();
printf("Bw:");
if (radio.type == SX1276) {
switch (radio.RegModemConfig.sx1276bits.Bw) {
case 0: printf("7.8KHz "); break;
case 1: printf("10.4KHz "); break;
case 2: printf("15.6KHz "); break;
case 3: printf("20.8KHz "); break;
case 4: printf("31.25KHz "); break;
case 5: printf("41.7KHz "); break;
case 6: printf("62.5KHz "); break;
case 7: printf("125KHz "); break;
case 8: printf("250KHz "); break;
case 9: printf("500KHz "); break;
default: printf("%x ", radio.RegModemConfig.sx1276bits.Bw); break;
}
} else if (radio.type == SX1272) {
switch (radio.RegModemConfig.sx1272bits.Bw) {
case 0: printf("125KHz "); break;
case 1: printf("250KHz "); break;
case 2: printf("500KHz "); break;
case 3: printf("11b "); break;
}
}
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void printSf()
{
// spreading factor same between sx127[26]
printf("sf:%d ", radio.getSf());
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void printTxContinuousMode()
{
printf("TxContinuousMode:%d ", radio.RegModemConfig2.sx1276bits.TxContinuousMode); // same for sx1272 and sx1276
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void printAgcAutoOn()
{
printf("AgcAutoOn:%d", radio.getAgcAutoOn());
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void printRxPayloadCrcOn()
{
bool on = radio.getRxPayloadCrcOn();
//printf("RxPayloadCrcOn:%s ", on ? "on" : "off");
if (on)
printf("RxPayloadCrcOn:1 = Tx CRC Enabled\r\n");
else
printf("RxPayloadCrcOn:1 = no Tx CRC\r\n");
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void printLoraIrqs_(bool clear)
{
//in radio class -- RegIrqFlags_t RegIrqFlags;
//already read RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
printf("\r\nIrqFlags:");
if (radio.RegIrqFlags.bits.CadDetected)
printf("CadDetected ");
if (radio.RegIrqFlags.bits.FhssChangeChannel) {
//radio.RegHopChannel.octet = radio.read_reg(REG_LR_HOPCHANNEL);
printf("FhssChangeChannel:%d ", radio.RegHopChannel.bits.FhssPresentChannel);
}
if (radio.RegIrqFlags.bits.CadDone)
printf("CadDone ");
if (radio.RegIrqFlags.bits.TxDone)
printf("TxDone ");
if (radio.RegIrqFlags.bits.ValidHeader)
printf("[42mValidHeader[0m ");
if (radio.RegIrqFlags.bits.PayloadCrcError)
printf("[41mPayloadCrcError[0m ");
if (radio.RegIrqFlags.bits.RxDone)
printf("[42mRxDone[0m ");
if (radio.RegIrqFlags.bits.RxTimeout)
printf("RxTimeout ");
printf("\r\n");
if (clear)
radio.write_reg(REG_LR_IRQFLAGS, radio.RegIrqFlags.octet);
}
#endif /* _DEBUG_ */
#ifdef _DEBUG_
void lora_print_status()
{
uint8_t d;
if (radio.type == SX1276)
printf("\r\nSX1276 ");
else if (radio.type == SX1272)
printf("\r\nSX1272 ");
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
if (!radio.RegOpMode.bits.LongRangeMode) {
printf("FSK\r\n");
return;
}
lora_print_dio();
printf("LoRa ");
// printing LoRa registers at 0x0d -> 0x3f
radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
radio.RegModemConfig2.octet = radio.read_reg(REG_LR_MODEMCONFIG2);
printCodingRate(false); // false: transmitted coding rate
printHeaderMode();
printBw();
printSf();
printRxPayloadCrcOn();
// RegModemStat
printf("ModemStat:0x%02x\r\n", radio.read_reg(REG_LR_MODEMSTAT));
// fifo ptrs:
radio.RegPayloadLength = radio.read_reg(REG_LR_PAYLOADLENGTH);
radio.RegRxMaxPayloadLength = radio.read_reg(REG_LR_RX_MAX_PAYLOADLENGTH);
printf("fifoptr=0x%02x txbase=0x%02x rxbase=0x%02x payloadLength=0x%02x maxlen=0x%02x",
radio.read_reg(REG_LR_FIFOADDRPTR),
radio.read_reg(REG_LR_FIFOTXBASEADDR),
radio.read_reg(REG_LR_FIFORXBASEADDR),
radio.RegPayloadLength,
radio.RegRxMaxPayloadLength
);
radio.RegIrqFlags.octet = radio.read_reg(REG_LR_IRQFLAGS);
printLoraIrqs_(false);
radio.RegHopPeriod = radio.read_reg(REG_LR_HOPPERIOD);
if (radio.RegHopPeriod != 0) {
printf("\r\nHopPeriod:0x%02x\r\n", radio.RegHopPeriod);
}
printf("SymbTimeout:0x%03x ", radio.read_u16(REG_LR_MODEMCONFIG2) & 0x3ff);
radio.RegPreamble = radio.read_u16(REG_LR_PREAMBLEMSB);
printf("PreambleLength:0x%03x ", radio.RegPreamble);
if (radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER || radio.RegOpMode.bits.Mode == RF_OPMODE_RECEIVER_SINGLE) {
d = radio.read_reg(REG_LR_RSSIVALUE);
printf("rssi:%ddBm ", d-120);
}
printTxContinuousMode();
printf("\r\n");
printAgcAutoOn();
if (radio.type == SX1272) {
printf(" LowDataRateOptimize:%d\r\n", radio.RegModemConfig.sx1272bits.LowDataRateOptimize);
}
printf("\r\nHeaderCount:%d PacketCount:%d, ",
radio.read_u16(REG_LR_RXHEADERCNTVALUE_MSB), radio.read_u16(REG_LR_RXPACKETCNTVALUE_MSB));
printf("Lora detection threshold:%02x\r\n", radio.read_reg(REG_LR_DETECTION_THRESHOLD));
radio.RegTest31.octet = radio.read_reg(REG_LR_TEST31);
printf("detect_trig_same_peaks_nb:%d\r\n", radio.RegTest31.bits.detect_trig_same_peaks_nb);
if (radio.type == SX1272) {
radio.RegModemConfig.octet = radio.read_reg(REG_LR_MODEMCONFIG);
printf("LowDataRateOptimize:%d\r\n", radio.RegModemConfig.sx1272bits.LowDataRateOptimize);
} else if (radio.type == SX1276) {
radio.RegModemConfig3.octet = radio.read_reg(REG_LR_MODEMCONFIG3);
printf("LowDataRateOptimize:%d\r\n", radio.RegModemConfig3.sx1276bits.LowDataRateOptimize);
}
printf("\r\n");
//printf("A %02x\r\n", radio.RegModemConfig2.octet);
}
#endif /* _DEBUG_ */
void
service_radio()
{
service_action_e act = radio.service();
switch (act) {
case SERVICE_READ_FIFO:
printf("SERVICE_READ_FIFO\r\n");
// clear Irq flags
radio.write_reg(REG_LR_IRQFLAGS, radio.RegIrqFlags.octet);
break;
case SERVICE_TX_DONE:
printf("SERVICE_TX_DONE\r\n");
break;
case SERVICE_ERROR:
printf("error\r\n");
break;
} // ...switch (act)
}
int
main(void)
{
#ifdef _DEBUG_
pc.baud(57600);
pc.printf("\r\nstart\r\n");
#endif /* _DEBUG_ */
while (1) {
//try to read a msg
if (hid.readNB(&recv_report)) {
HidCmdProcess();
}
#ifdef _DEBUG_
if (pc.readable()) {
char c = pc.getc();
if (c == 'v') {
pc.printf("verbose ");
if (verbose) {
verbose = 0;
pc.printf("off");
} else {
verbose = 1;
pc.printf("on");
}
pc.printf("\r\n");
} else if (c == '.') {
common_print_status();
if (radio.RegOpMode.bits.LongRangeMode)
lora_print_status();
else
printf("FSK\r\n");
} else if (c == 't') {
int i;
printf("tx\r\n");
radio.set_opmode(RF_OPMODE_TRANSMITTER);
for (i = 0; i < 20; i++) {
radio.RegOpMode.octet = radio.read_reg(REG_OPMODE);
printf("opmode:%02x\r\n", radio.RegOpMode.octet);
}
} else if (c == 'T') {
printf("start_tx\r\n");
radio.RegPayloadLength = 8;
radio.write_reg(REG_LR_PAYLOADLENGTH, radio.RegPayloadLength);
radio.lora_start_tx(8);
} else if (c == 'e') {
printf("service_radio\r\n");
service_radio();
} else if (c == 's') {
radio.set_opmode(RF_OPMODE_STANDBY);
printf("standby\r\n");
} else if (c == 'h') {
printf("hwreset\r\n");
radio.hw_reset();
radio.init(); //SX1272Init( );
} else if (c == 'l') {
radio.SetLoRaOn(!radio.RegOpMode.bits.LongRangeMode);
printf("LongRangeMode:%d\r\n", radio.RegOpMode.bits.LongRangeMode);
} else if (c == '?') {
printf("s standby\r\n");
printf("T lora_start_tx(8)\r\n");
printf(". print status\r\n");
printf("v toggle verbose\r\n");
printf("t tx mode test\r\n");
printf("e manualy service radio once\r\n");
printf("h hwreset, init\r\n");
printf("l toggle lora mode\r\n");
}
} // ...if (pc.readable())
#endif /* _DEBUG_ */
} // ...while (1)
}
