0,0 → 1,413 |
|
|
/** INCLUDES *******************************************************/ |
|
|
#include "GenericTypeDefs.h" |
#include "Compiler.h" |
#include "HardwareProfile.h" |
#include "USB/usb.h" |
#include "usbavrcmd.h" |
|
#include "user.h" |
#include <math.h> |
|
#include <stdlib.h> |
#include <string.h> |
#include <ctype.h> |
|
#if defined (UBW) |
#include <delays.h> |
#include <i2c.h> |
#include <EEP.h> |
|
#elif defined (UBW32) |
#include <peripheral/i2c.h> |
#include <dee_emulation/dee_emulation_pic32.h> |
|
#endif |
|
|
/******************************************************************** |
* Section B: EP0 Buffer Space |
*******************************************************************/ |
extern volatile CTRL_TRF_SETUP SetupPkt; // 8-byte only |
extern volatile BYTE CtrlTrfData[USB_EP0_BUFF_SIZE]; |
|
#pragma udata |
|
WORD_VAL FilterCrossOver[8]; |
float FilterSwitchOver[7]; |
|
WORD_VAL LPFCrossOver[8]; |
float LPFSwitchOver[7]; |
|
#pragma code |
|
void USBCheckUBWRequest(void) |
{ |
unsigned char paddle_byte; |
unsigned int eep_adr; |
WORD_VAL w; |
unsigned int i, j; |
unsigned char IO_data; |
|
#if defined (UBW32) |
unsigned int value; |
unsigned int number_of_filter_bytes; |
#else |
unsigned char number_of_filter_bytes; |
#endif |
|
|
|
if(SetupPkt.RequestType == USB_SETUP_TYPE_STANDARD_BITFIELD) return; // only deals with non-standard, ie user requests |
|
command = SetupPkt.bRequest; // save the command of the user request from the setuppacket |
// it will be used for subsequent data transfer |
|
switch(command) |
{ |
|
case CMD_GET_CW_KEY: |
|
paddle_byte = 0x22; // 00100010 |
if (!PADDLE_DIT) paddle_byte &= 0xdf; // 11011111 |
if (!PADDLE_DAH) paddle_byte &= 0xfd; // 11111101 |
if (RXTX) paddle_byte |= 0x10; // PB4 is the ATTINY PTT_OUT pin 00010000 |
else paddle_byte &= 0xef; // 11101111 |
|
replybuf[0] = paddle_byte; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 1; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_SET_USRP1: // Set RxTx and get Paddle status |
paddle_byte = 0x22; // 00100010 |
if ( SetupPkt.W_Value.v[0] ){ |
RXTX = 1; // Set PTT |
paddle_byte |= 0x10; // 00010000 |
} |
else{ |
RXTX = 0; |
paddle_byte &= 0xef; // 11101111 |
}; |
|
|
if (!PADDLE_DIT) paddle_byte &= 0xdf; // 11011111 |
if (!PADDLE_DAH) paddle_byte &= 0xfd; // 11111101 |
|
replybuf[0] = paddle_byte; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 1; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_SET_FREQ_REG: // Control Transfer Rx of data from HOST->UBW |
case CMD_SET_LO_SM: |
case CMD_SET_FREQ: |
case CMD_SET_XTAL: |
case CMD_SET_STARTUP: |
case CMD_SET_PPM: |
|
wCount = SetupPkt.wLength; |
outPipes[0].wCount.Val = SetupPkt.wLength; |
outPipes[0].pFunc = &Read_Command_Into_Buffer; |
outPipes[0].pDst.bRam = (BYTE*) &command_buffer[current_command_in].data[0]; |
outPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_GET_PIN: // read ports |
IO_data = 0x0d; // 00001101 |
if (PADDLE_DAH) IO_data |= 0x02; // PB1 |
if (BPF_S0_STATE) IO_data |= 0x10; // PB4 |
if (BPF_S1_STATE) IO_data |= 0x20; // PB5 |
|
replybuf[0] = IO_data; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 1; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_SET_PORT: // set ports |
IO_data = SetupPkt.W_Value.v[0]; |
if (!abpf_flag){ |
if (IO_data & 0x10) BPF_S0 = 1; |
else BPF_S0 = 0; |
if (IO_data & 0x20) BPF_S1 = 1; |
else BPF_S1 = 0; |
}; |
break; |
|
case CMD_SET_IO: // set i/o bits |
IO_data = SetupPkt.W_Index.v[0] & 0x03; // only 2 bits active 00000011 |
|
if (!abpf_flag) { // abpf inactive |
if (IO_data & 0x01) BPF_S0 = 1; // Simulate IO_PIN1 in ATTINY |
else BPF_S0 = 0; |
if (IO_data & 0x02) BPF_S1 = 1; // Simulate IO_PIN2 in ATTINY |
else BPF_S1 = 0; |
} |
|
IO_data = BPF_S0_STATE; // read back status of BPF select pins |
if (BPF_S1_STATE) IO_data |= 0x02; |
else IO_data &= 0x01; |
|
replybuf[0] = IO_data; |
replybuf[1] = 0x00; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 2; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_GET_IO: |
|
IO_data = BPF_S0_STATE; // status of BPF select pins |
if (BPF_S1_STATE) IO_data |= 0x02; |
else IO_data &= 0x01; |
|
replybuf[0] = IO_data; |
replybuf[1] = 0x00; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 2; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_SET_FILTER: // Set and Read filter crossover points |
i = SetupPkt.W_Index.Val; |
if (i < 256){ // Rx Filter |
number_of_filter_bytes = NUM_BPF * 2; |
inPipes[0].pSrc.bRam = (BYTE*)&FilterCrossOver[0]; // Set source |
|
if (i < NUM_BPF) { |
FilterCrossOver[i].Val = SetupPkt.W_Value.Val; |
if (i != (NUM_BPF-1)) FilterSwitchOver[i] = Cross2Switch(FilterCrossOver[i]); |
else abpf_flag = SetupPkt.W_Value.Val; |
} |
} |
else{ // Tx filter |
number_of_filter_bytes = 16; |
inPipes[0].pSrc.bRam = (BYTE*)&LPFCrossOver[0]; // Set source |
|
j = i - 256; |
if ( j < 8){ |
LPFCrossOver[j].Val = SetupPkt.W_Value.Val; |
if (j != 7) LPFSwitchOver[j] = Cross2Switch(LPFCrossOver[j]); |
}; |
}; |
|
// now that a filter value of filter enable/disable value is set, update the EEPROM |
#if defined (UBW) |
for (i = 0; i < NUM_BPF; i++){ |
Write_b_eep((i * 2 + F_CROSS_OVER +1), FilterCrossOver[i].v[0]); |
Busy_eep(); |
Write_b_eep((i * 2 + F_CROSS_OVER + 1 + 1), FilterCrossOver[i].v[1]); |
Busy_eep(); |
} |
#elif defined (UBW32) |
for (i =0; i < NUM_BPF; i++) DataEEWrite( FilterCrossOver[i].Val , (i + F_CROSS_OVER +1)); |
#endif |
|
#if defined (UBW) |
for (j = 0; j < 8; j++){ |
Write_b_eep(( j * 2 + F_CROSS_OVER +17), LPFCrossOver[j].v[0]); |
Busy_eep(); |
Write_b_eep(( j * 2 + F_CROSS_OVER +17 + 1), LPFCrossOver[j].v[1]); |
Busy_eep(); |
} |
Write_b_eep(F_CROSS_OVER, F_CROSS_OVER_VALUE); |
Busy_eep(); |
#elif defined (UBW32) |
for (j = 0; j < 8; j++){ |
DataEEWrite( (unsigned int)LPFCrossOver[j].Val , (j + F_CROSS_OVER +9)); |
}; |
DataEEWrite(F_CROSS_OVER_VALUE, F_CROSS_OVER); |
#endif |
|
|
inPipes[0].wCount.v[0] = number_of_filter_bytes; // Set data count |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_SET_SI570: // SI570: write byte from register index |
i2c_adr = SetupPkt.W_Value.v[0]; |
#if defined (UBW) |
IdleI2C(); |
StartI2C(); |
IdleI2C(); |
WriteI2C( i2c_adr <<1); |
WriteI2C( SetupPkt.W_Value.v[1]); // register = byte 3 |
WriteI2C( SetupPkt.W_Index.v[0]); // value to write to register |
StopI2C(); |
IdleI2C(); |
#elif defined (UBW32) |
IdleI2C1(); |
StartI2C1(); |
IdleI2C1(); |
MasterWriteI2C1( i2c_adr <<1); |
MasterWriteI2C1( SetupPkt.W_Value.v[1]); // register = byte 3 |
MasterWriteI2C1( SetupPkt.W_Index.v[0]); // value to write to register |
StopI2C1(); |
IdleI2C1(); |
#endif |
|
replybuf[0] = 0; // just say no errors |
|
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 1; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
|
case CMD_GET_LO_SM: // return sub mul |
for (i=0; i<4; i++) replybuf[i] = f_sub.bytes[i]; |
for (i=0; i<4; i++) replybuf[i+4] = f_mul.bytes[i]; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 8; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
|
case CMD_GET_FREQ: // return set freq, ie no offset/mul |
avr_freq.qw = set_frequency * (double)(1L << 21); |
inPipes[0].pSrc.bRam = (BYTE*)&avr_freq.bytes[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 4; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_GET_PPM: // return smooth tune in ppm |
w.Val = Smooth_double * 1000000L; |
inPipes[0].pSrc.bRam = (BYTE*)&w.v[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 2; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_GET_STARTUP: // return init startup freq |
|
#if defined(UBW) |
for (i=0; i<4; i++) avr_freq.bytes[i] = Read_b_eep(i + F_INIT_FREQ +1); |
#elif defined(UBW32) |
for (i=0; i<4; i++) { |
DataEERead(&value, (i + F_INIT_FREQ +1)); |
avr_freq.bytes[i] = value; |
}; |
#endif |
|
inPipes[0].pSrc.bRam = (BYTE*)&avr_freq.bytes[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 4; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_GET_XTAL: // return fcryst |
inPipes[0].pSrc.bRam = (BYTE*)&fcryst_freq.bytes[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 4; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_GET_SI570: // SI570: read out frequency control registers |
i2c_adr = SetupPkt.W_Value.v[0]; |
ReadRegs(); |
inPipes[0].pSrc.bRam = (BYTE*)®isters[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 6; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
case CMD_GET_I2C_ERR: // return # of i2c errors, set to zero always |
replybuf[0] = 0; // No errors :) |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 1; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
|
case CMD_SET_I2C_ADDR: // Reset EEPROM to default values if 255 |
// Otherwise just set i2c address |
|
if (SetupPkt.W_Value.v[0] == 0xff){ |
#if defined (UBW) |
Write_b_eep(F_CAL_DONE, 0xff); |
Busy_eep(); |
Write_b_eep(F_INIT_FREQ, 0xff); |
Busy_eep(); |
Write_b_eep(F_SMOOTH, 0xff); |
Busy_eep(); |
Write_b_eep(F_SUB_MUL, 0xff); |
Busy_eep(); |
Write_b_eep(F_CROSS_OVER, 0xff); |
Busy_eep(); |
#elif defined (UBW32) |
DataEEWrite( (unsigned int) 0xff, F_CAL_DONE); |
DataEEWrite( (unsigned int) 0xff, F_INIT_FREQ); |
DataEEWrite( (unsigned int) 0xff, F_SMOOTH); |
DataEEWrite( (unsigned int) 0xff, F_SUB_MUL); |
DataEEWrite( (unsigned int) 0xff, F_CROSS_OVER); |
#endif |
|
i2c_adr = 0x55; |
} |
else { |
i2c_adr = SetupPkt.W_Value.v[0]; |
}; |
|
replybuf[0] = 0x00; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 1; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
|
|
case CMD_GET_VERSION: // return version 15.10 |
replybuf[0] = VERSION_MINOR; |
replybuf[1] = VERSION_MAJOR; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0]; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 2; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
|
default: // Command not supported |
|
replybuf[0] = 0xff; |
inPipes[0].pSrc.bRam = (BYTE*)&replybuf[0] ; // Set Source |
inPipes[0].info.bits.ctrl_trf_mem = USB_EP0_RAM; // Set memory type |
inPipes[0].wCount.v[0] = 1; // Set data count |
inPipes[0].info.bits.busy = 1; |
break; |
}//end switch |
|
|
} |
|
|
void Read_Command_Into_Buffer(void) |
{ |
|
if (command_count >= COMMAND_BUFFER_SIZE){ // buffer full |
current_command_out++; // discards oldest command |
if (current_command_out >= COMMAND_BUFFER_SIZE) current_command_out = 0; |
command_count--; // now one command less (discarded) |
}; |
command_buffer[current_command_in].command = command; |
command_buffer[current_command_in].wCount = wCount; |
// data already copied to command_buffer before this outpipe pFunc is called |
current_command_in++; |
if (current_command_in >= COMMAND_BUFFER_SIZE) current_command_in = 0; |
command_count++; |
} |