SoftRock V9.0 Receiver

Firmware USB AVR Si570 controler.

Home @


I like to play around with embedded software. I also build the SoftRock V9.0 with is using the ATTiny45 / ATTiny85 chip for controlling the receiver and handling the USB bus. Because of a bug in the old firmware I was become interested in the firmware and start extending the functionality, the whole process can be found on this page.
The first version of this firmware was build by Tom Baier (DG8SAQ) based on a Atmel AVR ATtiny45 chip. The firmware used the free V-USB Library to support low-speed USB-1.1 protocol.

This firmware is the the official supplied firmware in the SoftRock / Ensemble RX and RXTX kits of Tony Parks (KB9YIG) that are using a Si570 chip from Silicon Laboratories (SiLabs).

To configure the firmware there is a Windows configuration tool CFGSR. And if you want to use the SoftRock V9.0 with WinRad from Alberto I2PHD you may like to use my ExtIO_Si570 DLL. Also the perfect WinRad successor HDSDR can be used with the ExtIO_Si570 DLL.

Reprogramming of the ATtiny45 / ATtiny85 chip can only be done with a AVR high voltage programmer or a tool like my fuse bit restore.

I like to thank Prof. Dr. Thomas C. Baier for the publication of the initial software.


Page direct links:


Hardware Suppliers.

The following hardware suppliers are delivering RX or RXTX hardware based upon this firmware:


Version 15.1: Bug fixed.

The same software in the SoftRock-V9.0 board gives a problem because the SoftRock-V9.0 is using different power for the AVR chip (5V USB) and the Si570 chip (3.3V RX). When the power supply's are switched ON on the same moment (one dubble power switch) there is no problem. Switching only the AVR (or switching the RX off) will hang the software and the USB connection will be broken.

I changed the software so that the software will not hang on that bug. I also cleaned the software by removing many not used (I hope :-) commands. Compiled it with the WinAVR gcc compiler (WinAVR-20071221) and the lates version of the V-USB library (usbdrv-20081022).

 * Modifications by Fred Krom, PE0FKO at Nov 2008
 * - Fixed hang on no pull up of SCL line i2c to Si570 (or power down of Si590 in SR-V90)
 * - Initialize Si570 when seen on the i2c bus
 * - Compiler (WinAVR-20071221) optimized the i2c delay loop a way!
 * - AVR USB Version usbdrv-20081022
 * - Source cleanup and split in deferend files.
 * - Remove many debug USB command calls!
 * - Add command 0x31, write only the Si570 registers (change freq max 3500ppm)

Version 15.2: Si570 Algorithme.

In the new version V15.2 I changed the code for calculating the Si570 registers. The algorithm searched for the lowest DCO frequency and will calculate the full 38 bits of the RFREQ register. That is done in less code than the older versions and much faster.
The old code was very bad in calculating the register value, most programs do not use this function bacause the frequency was far from the specified one (< 5KHz). The programs will calculate the si570 registers and will send them to the chip. The USB interface will be chip dependent and the interface can not be used for controlling a DDS.
It is necessary to use command such as "set the freq to 7.040MHz" and not commands like "Set the Si570 registers to 0xAB, 0xCD...".

But for normal users the code change is not that important (maybe the precise frequency?). The speed improvements from 2ms to 0.37ms will not be mention by normal users, and that the chip uses less code...
But for future improvements you will need the speed and free code (maybe).
The next I working on is the fraction tuning, when the chip's frequency has to be changed a little bit there is no need to stop and start the chip again. A smooth tuning is then possible for small (+/-3500PPM) frequency changes.

 * - Change the Si570 register calculation and now use the full 38 bits of the chip!
 *   Is is acurate, fast and small code! It cost only 350us (old 2ms) to calculate the new registers.
 * - Add command 0x3d, Read the actual used xtal frequenty (4 bytes, 24 bits fraction, 8.24 bits)

Version 15.3: Automatic Smooth Tune.

In the new version V15.3 I added the "automatic smooth tune" (AST) functionality and the I/O function. The AST will work only on the "set freq by value" and not on the register setting. The AST is automatic and enabled by default. The range (+/- 3500PPM) can be changed and read from the device, setting it on zero will disable the function.
The I/O function works in one call with a value for the I/O direction (Input or Output) and a bit value for the Output bit and it will return all the bits in one word. This hardware only support bit0 and bit1.
There are support command for setting and reading the crystal frequency, startup frequency and the AST PPM value.

Version 15.4: Automatic Band Pass Filter selection

In this new version V15.4 I added the "Automatic Band Pass Filter selection" (ABPF) functionality for the Softrock V9 BPF. The device will accept 3 filter cross over values and will automatic select between the four filters. De functionality can be disabled by software. By changing the main.c function I released a lot of code space to implement this and maybe other functions.
This functionality (also the AST) will only work with the call "set frequency by value" and not the "set frequency by Si570 registers". Now there is still room for some more code, maybe we can change both functions to work with the register call?
For application software that want to see the difference between the old and new firmware, I changed the USB version number. That will give one small problem, this software will ask for the driver the very first time it is plugged into a PC. The same as the old firmware did the first time. The serial number will not be checked in most existing software (I hope) so no change had to be made there.

Version 15.5: Smooth tune and band pass filter to the "Set freq by Si570 registers" command.

Many existing SDR receivers are using the "Set freq by Si570 registers" command and not the (easier to use) "Set freq by value" command. That is due to history.
My smooth tune and automatic band pass filter are working in the previous versions only on the ".. value" command. Now they are also working on the ".. Si570 register" command. The working behind it is that from the given Si570 registers the requested frequency is calculated (< 100 us) and that frequency is passed to the "Set freq by value" command. The calculations are done with all the precision (bits) of the Si570 chip.
I will recommend that new SDR software is going to use the "Set freq by value" command despite this functionality.

Version 15.6: Bug fix.

This version is a small Bug fix, after rebooting the PC with the USB connected there will be no USB connection. That is fixed, something with the watchdog timer. There was also a small problem, when reading the frequency from the USB controller it will return the smooth tune center frequency and not the oscillating frequency. No application programs is using that call, only my own Winrad dll for information only.

Version 15.7: Minor updates.

This is the latest version of my Si570 Firmware upgrade.
It is tested on the SoftRock V9 (with and without the BPF) and SoftRock RXTX 6.3 hardware and it is compatible with most SDR Radio software that support the Si570 driver. For use with the SoftRock RXTX you will need to disable the ABPF settings!
I tested it with WinRad ExtIO_Si570.dll, WinRad ExtIO_si570_usb.dll, Rocky V3.6 and PowerSDR-IQ V1.12.3.
Because the basic command's are not changed from the original firmware, I expect the software can be a good replacement for the original firmware. It will give the automatic antenna tuning and smooth tune functionality and some bug fixes.
Only be aware that some software my depend on functionality that is supported in the original but not in this firmware! In the original software there are command's to handle all kind of I2C functions. For example the USB_Synth program used a calibration with the chip factory default startup frequency (Menu "Setup", button "calibrate to factory startup frequency") that will not work with the new firmware (do not use it). The same function (and working for this firmware) will be found in the new WinRad
ExtIO_Si570_V0.7 dll version 0.7.


Version 15.8: Change in calculate frequency from Si570 registers.

I was not right, there is a new version release. I do like a power of two!
In a mail from Alex, he mention a nice future that he was expecting to work in my firmware. But is was not working, never crossed my mind until then.
I did try to make the difference between the two "set frequency" calls minimal. There was only a difference between them in the calibration. Using the "set freq by value" call the crystal frequency in the firmware must be calibrated, using the "set freq by Si570 registers" call the application crystal frequency must be calibrated.
I changed it that only the crystal frequency in the firmware had to be calibrated, and not the application program (SDR receiver) any more. But the application program must use the default crustal freq 114.285 MHz!
In the "set frequency by value" (command 0x32) the internal stored crystal frequency is used, when that crystal frequency is calibrated all the requested frequency's are correct. The command (0x30) "set frequency by Si570 registers" will calculate the frequency from the registers and then calls the "set frequency by value" command. In both calculations the internal crystal frequency is used and will be eliminated by the calculations!
The calculations are from registers to frequency to registers, and will give in the old version the same register settings as was input! That process was necessary because the smooth tune and ABPF setting where implemented in the "set frequency by value" command. But there is no calibration in that process any more, the application had to use the calibrated crystal frequency!
In the new version I calculate from the registers to frequency with the fixed value 114.285 MHz and then from the frequency to registers with the calibrated crystal frequency. That will deliver the calibrated frequency the application did calculate.
The application's are using as default the 114.285 MHz and that value had not to be changed any more!

It is a lot of text for a very small software update, only one variable changed to a fixed number!


Version 15.9: Disable I/O functions in case the ABPF is enabled.

If using the automatic band pass filters (ABPF) together with Rocky (maybe other SDR radio's to) there was a little problem discovered by Bob. Starting Rocky with a frequency that need a odd BPF (filter 1 and 3) the wrong filter was selected (filter 0 or 2). It was only at the start of Rocky, if a other LO was selected it chose the correct filter. The reason for that was that the correct filter was selected but Rocky did disable the first I/O bit, that I/O line is used in SoftRock RXTX 6.3 (and lower) for the TX enable line! Rocky did not know it is a RX only (SoftRock V9).
The problem can be changed in Rocky, I expect, but maybe the firmware must disable the I/O functions if the ABPF is using the I/O lines! That will solve all the problems of selecting the wrong BPF in the SoftRock V9.


Version 15.10: Add LO calculations.

The LO frequency send to the firmware can be changed by the firmware with a offset and a multiply factor, both numbers are fix point numbers with a [11.21] bits resolution.
The used calculation is "FSI570 = ( FLO - Offset ) * Multiply", the Offset is a signed number. The used default value's in the firmware are Offset=0.0 and Multiply=1.0, that will not change the LO frequency.
This feature can be used by frond end mixers with a fixed frequency, all kind of sub-sampling or other fraction multiply like the SoftRock VHF converter is using.
The LO frequency change will work on both set-frequency commands 0x30 and 0x32. To manage the offset and multiply factor two command's are added, one (0x31) to write the two numbers and one (0x39) to read the numbers.

For the use of this firmware in the "USB I2C Interface board" of Tony, the support for the second CW Key input (iambic keying) is added to the command 0x50 and 0x51. Also both command's will return a key open in case of the ABPF is enabled in the firmware. That will prevent the band filter selection bits being seen as CW key input.


Version 15.11: Bug fix with negative frequency offset value.

Using a negative offset value in the LO calculation will not add / subtract anything, in the previous firmware version.
The bug is fixed, and the code still fit in a ATtiny45 chip (2 bytes free) also the ATtiny85 version is available.
A other small change is made to the band crossover point values. The previous version did store the si570 running frequency, the new version will store the set frequency. In the default case of offset=0 and multiply=1 there is no change. And also the command 0x3A will return the set frequency and not the Si570 running frequency.
The change is completely handled by the configuration tool
ExtIO_Si570 version 0.9, use that or newer versions for this firmware version.


Version 15.12: Added the Intelligent Band Pass Filter.

This firmware version handles the separate band selection and filter crossover values differently. The previous versions used the filter crossover table to select the band / filter in an incrementing frequency sequence. The filter used for the ABPF was the same number as the band from the crossover table, therefore the actual filters used need to be in a increasing frequency sequence!
There was also, starting from version 15.10, an offset / multiply factor that recalculated the requested LO frequency.

Version 15.12 still uses the filter crossover table to select the frequency band. For every band (0..3) the filter number used can specified, also every band has it's own frequency offset / multiply factor! So the real filters do not necessarily have be in increasing frequency order (v9.0 RX option 2 BPF), also sub harmonic sampling can be specified differently for each band if required.
There is a change to the USB Serial-Number. This can be now set so that every device can have it's own unique serial number. This allows more than one device to be connected to the PC at the same time and used by different application software (if the application software is able to use that field to select a device).

A small change is made to the command 0x41 to set the I2C address, it will now also return the old I2C address and the address zero will not been set.

The sourcecode is made available on Google Code and as normal on this web-side.

One minor disadvantage of the extended functionality provided is that the code will no longer fit in the ATtiny45 chip, the bigger ATtiny85 device has to be used.


Version 15.13: Bug fix for Filter bank sequence.

Version 15.12 uses the filter crossover table to select the frequency band, for every frequency band (0..3) the filter number (0..3) used can specified. Only by a bug in the software, the output lines are not put in the requested filter value but the band value. The bug is now fixed (by changing a #ifdef to #if statement in DeviceSi570.c).

In the source there is now a compiler option to select the Si570 (LVPECL/LVDS/CML) grade used. For using the Si570 B or C grade chips there are divider values that may not be used (Si57x Speed Grading Implementation). The CMOS version of the Si570, used in the SoftRock40 kits, did not have the restriction, so in the generated .hex file the code is not implemented. This modification is not been tested, if you try this please send me a mail (I can generate a hex file for that).

There is a little change in the USB enumeration process. Before starting the process there is a delay of 100ms to settle down the electric signals. Maybe it can be a solution for some USB connect problems, also let me know if you find some difference with older versions (it is hard to test because I have no problems with it).


Version 15.14: Added Si570 speed grade and DCO range selection.

The Si570 chip is sold by Silabs in some different frequency ranges, they are called speed grade A, B or C chips. The difference in the chip are the allowed counter values (N1 and HS_DIV) what will limit the possible frequency with a specified DCO range ( 4850 - 5670 MHz).

The previous versions of the firmware did not exclude counter values (expecting a speed grade A chip). It is no problem for using a C grade chip if the frequency is below 261MHz (HF band usage of a SoftRock will run till 4*30 = 120MHz). Using the C grade chip (with the old firmware) will limit the max frequency below the Silabs specified value of 280MHz! For using the firmware in applications where the maximum frequency range is needed the speed grade (dividers) must be handled correct.

Using the new firmware V15.14 it will allow you to specify the chip grade (function 0x44). That will allow the C grade chip to run until 284MHz.
The firmware also allow you to change the minimum and maximum DCO frequency range out of the Silabs specification of 4.85 till 5.67 GHz, that may harm you Si570 chip (overheating the chip, you be warned).
The firmware has also a C+ grade, it is the C grade but also allowing the N1=4 and HS_DIV=4 divider setting. That also will extend the frequency range out of the specs (Amateur-Radio hobby is exploring the edges).

Extending the DCO value will allow you to reach higher frequencies and maybe remove some gaps in the frequency range of the Si570 chips. But it will be out of specification and will or will not work on every Si570 chip.

To explore the firmware algorithm and find the possible dividers for a frequency the excel sheet can be used.

To specify the chip grade or DCO value you will need the new CFGSR tool version minimal V2.3.

Grade
The divider restrictions for the Si570 speed grades or frequency grades are as follows
A
Grade A covers 10 to 945 MHz, 970 to 1134 MHz, and 1213 to 1417.5 MHz. Speed grade A device have no divider restrictions.
B
Grade B covers 10 to 810 MHz. Speed grade B devices disable the output in the following N1*HS_DIV settings: 1*4, 1*5
C
Grade C covers 10 to 280 MHz. Speed grade C devices disable the output in the following N1*HS_DIV settings: 1*4, 1*5, 1*6, 1*7, 1*11, 2*4, 2*5, 2*6, 2*7, 2*9, 4*4
The default speed grade in the firmware
C+
No official Silabs grade type!!
Grade C+ disable the output in the following N1*HS_DIV settings: 1*4, 1*5, 1*6, 1*7, 1*11, 2*4, 2*5, 2*6, 2*7, 2*9


Version 15.15: Support for new Si570 (7ppm temperature stability) chip. Si570 7ppm termperature stability

SiLabs did release a new version of the Si570 chip with some more functionality, bud one disadvantaged! The Si570 chip with the 7ppm temperature stability (The Si570-CCC) did change the internal registers number for the RFREQ settings. So the firmware need to be changed for that chip version!

The version V15.15 is capable of handling the new chip, even with a auto-detect of the chip type. The index for the RFREQ register can be specified by the firmware command 0x44, a index of 0 will trigger the auto-detect.
Also the new function Freezes the M Control Word to prevents interim frequency changes when writing RFREQ registers can be used. This function is not available on the old Si570 chip's, but specifying it will do no harm, it only cost some more time on the I2C bus with every frequency setting.

There are some more minor changes in the firmware. The few global register variables defined in the source are changed to ram variables. It cost some more speed and rom space, but the code is cleaner.
Also the speed on the I2C bus is changed to a lower value, I did see my Si570 chip in the SoftRock did give some unpredictable return values. Don't expect the slower I2C bus will be a big deal.


Supported Firmware functionality.

The firmware support the following functionality on both set frequency commands 0x30 and 0x32.

Function
Version Description
Smooth tune
V15.3
Tuning without clicking on every frequency change. The smooth tune is only possible if the frequency change is no more that 3500ppm (that value can be changed, 0 is disabling the functionality)
Automatic Band Pass Filter
V15.4
Selecting automatic one of the four band pass filter for every LO frequency. The functionality can be enabled / disabled and will use the two I/O lines on the SoftRock V9. If enabled other I/O settings are disabled.
V15.12: The used hardware filter for a band can be user specified.
One site calibration
V15.8
Only the firmware had te be calibrated and not the SDR PC Software. The calibration can be done with WinRad and my control ExtIO_Si570 DLL. Keep (if it can be changed) the crystal frequency in the PC SDR application on the default (114.285 MHz) value.
Local ocilator calculation
V15.10
The LO frequency can be changed by a offset and multiply factor. The real Si570 frequency will be calculated for every frequency change by formula "FSI570 = ( FLO - Offset ) * Multiply". The offset and multiply is a fixed point number stored in eeprom and can be changed by the software.
V15.12: There is a offset / multiply factor for every band.
Si570 Speed grade
V15.14
Select the Si570 speed grade and set the Si570 DCO freqency range.
Si570 RFREQ index
V15.15
Select the Si570 RFREQ index for the used Si570 chip.


Supported SDR Receivers.

The firmware has been tested with some the most popular (for what I know) free SDR receivers to check the functionality from the above table.

SDR Software
Version
DLL
Description
WinRad
1.32, 1.42
Yes
Winrad by Alberto, I2PHD.
HDSDR
v1.0
Yes
Mario Taeubel, Based on WinRad
WRplus
v1.00
Yes
Sandro Sfregola, Based on WinRad
Rocky
3.6
No
Rocky by Alex Shovkoplyas, VE3NEA.
PowerSDR-IQ
1.12.20
No
PowerSDR-IQ by Christos Nikolaou, SV1EIA.
PowerSDR-SR40
1.9.0
No
PowerSDR-SR40 by Guido ten Dolle, PE1NNZ.
PowerSDR
1.18.0
Yes
PowerSDR by FlexRadio Systems.
The supported DLL is a changed version from pe1nnz to support this firmware.
SDR-Radio
1.0
No
SDR-RADIO.com GmbH, Simon HB9DRV.
CfgSR
1.2
Yes
SoftRock configuration program.


Firmware set-up tips & tricks.

To setup the firmware the configuration tool
ExtIO_Si570 can be used.
To learn all about the possible configuration, please read the "PE0FKO SoftRock AVR Firmware User Guide Issue 1_1" created by Bob, G8VOI.
There is also a very nice documents ("v9.0 VHF converters and firmware set-up") describing a lot about the special firmware setup's made by Bob, G8VOI that can be found at this link.



Download Firmware source and .hex files.

The sourcecode is also available on
Google Code.

V15.1 at 02/12/2008: First release of PE0FKO.
V15.2 at 19/12/2008: Change the Si570 code.
V15.3 at 02/01/2009: Add Automatich smooth tune.
V15.4 at 06/01/2009: Add Automatic Band Pass Filter Selection.
V15.5 at 14/01/2009: Add the Smooth tune and band pass filter to the "Set freq by Si570 registers" command.
V15.6 at 17/01/2009: Bug fix, PC reboot connection. Return frequency was smooth tune center frequency.
V15.7 at 25/01/2009: Minor updates.
V15.8 at 11/02/2009: Change in calculate frequency from Si570 registers.
V15.9 at 19/02/2009: Disable I/O functions in case the ABPF is enabled.
V15.10 at 12/03/2009: LO frequency subtract and multiply.
V15.11 at 27/07/2009: Bug fix with negative frequency subtract value.
V15.12 at 28/09/2009: Added the Inteligent Band Pass Filter.
V15.13 at 18/06/2010: Bug fix for Filter bank sequence.
V15.14 at 06/01/2011: Add Si570 speed grade and DCO range selection.
V15.15 at 11/12/2011: Add Si570 RFREQ index and autodetect.

Firmware version V15.15

Download the source AVR-FirmwareV15.15.zip file.
Download the ATtiny85 hex AVR-FirmwareV15.15-ATtiny85.hex file.

Firmware version V15.12

Download the source AVR-FirmwareV15.12.zip file.
Download the ATtiny85 hex AVR-FirmwareV15.12-ATtiny85.hex file.

OLD Firmware version V15.11 (runs in 4K ATtiny45)

Download the source AVR-FirmwareV15.11.zip file.
Download the ATtiny45 hex AVR-FirmwareV15.11-ATtiny45.hex file.
Download the ATtiny85 hex AVR-FirmwareV15.11-ATtiny85.hex file 1).



Install the PC driver software automatic.

There is now a simple way to install the driver software for a Windows system (XP, Vista, 7, 8 and Windows10), just run the installer that can be downloaded over here PE0FKO-USB-Driver-Installer.exe. Like to install it by hand, read the next paragrapf.

The installer must be run before connecting the SoftRock hardware and it will install the Amateur Radio Root Certificate V2 with the tool ARCA.exe and then it will install automatic the LibUSB-Win32 driver .inf file.

Install the PC driver software by hand.

For installing the device you will need the USB PC driver software PE0FKO-USB-Driver-1.2.6.0.zip, it is based on the open-source LibUSB-Win32 software.
First extract the .zip file to a temporary directory (on the Desktop).

The installation process is different for the Windows version you are using (2000(not tested), XP, Vista(not tested), Window-7), special care must be taken when installing it on a 64bits system (Window-7, Vista).

Install Window-XP.

Plug in the device and it will show "Found new hardware DG8SAQ-I2C". Direct the wizard to the place where the software was stored and the software will be installed.

Install Window-7 (64bits).

For using this kernelmode device driver on a 64bits Windows system the driver must be signed, other wise it will not install. The LibUSB-Win32 group did sign the new driver (V1.2.0.0, 2010/07/10) with a correct certificate.
To install the driver there are two ways to do it. The first one "get a nasty error message" and continue or you can install a Root certfificate on your system and smoothly install the driver.
The installation on a Windows-7 system will not start automatich when the devices is plugged in. Go to the Device manager and find the "DG8SAQ-I2C" device.
Then take the next steps:

The device

Install Amateur Radio Root certificate.

To install the Amateur Radio Root certificate follow the steps on the Amateur Radio Certificate Authority V2.


Upgrading Firmware.

Upgrading the firmware will be done, in most cases, by changing the old ATtiny45 / Attiny85 by a new one with the correct code and fuse bits loaded.
Cecil, K5NWA can also supply the programmed chip via his website
The Parts Place, order a ATTINY85-20 chip with the firmware already programmed.

The original chip can be upgraded but it will cost some hardware and AVR micro controller programming skills.
To reprogram the original ATtiny45 / Attiny85 chip from Tony you will need to release the RSTDISBL fuse bit, that can be done with a fuse bit restore tool, or by using a AVR high voltage programmer. After restoring the RSTDISBL fuse bit a normal AVR ISP programmer can be used.

With a *new* Attiny45 / Attiny85 chip, the fuse bit restore is not necessary, until you program the RSTDISBL fuse bit to use the PB5 as a extra I/O line.

For people that are willing to learn something about the programming of the Atmel AVR chip's, there is a lot of information on the web.
Also Bob, G8VOI created a very nice document ("A Beginners Guide to Programming the Atmel ATtiny") about the steps to be taken to (re)program the ATTiny45 or ATTiny85 chip with this firmware. The document and other documents from Bob can be found at this webpage.

PonyProg.

Bob G8VOI did some excellent field work for the programming of the firmware in a new ATtiny45 / Attiny85 chip with PonyProg, and created a easy to use PonyProg script file. Please read this document "Beginners Guide to Programming the Atmel ATtiny45 and ATtiny85" by Bob, G8VOI. Hopefully that should make it very easy for a beginner to program their own chip.


************************************************************************
**
** Project......: Firmware USB AVR Si570 controler.
**
** Platform.....: ATtiny45
**
** Licence......: This software is freely available for non-commercial 
**                use - i.e. for research and experimentation only!
**                Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH
**                Based on ObDev's AVR USB driver by Christian Starkjohann
**
** Programmer...: F.W. Krom, PE0FKO.
**                Thanks to Tom Baier DG8SAQ for the initial program.
**                Thanks to Alex Lee for the command 0x17 description.
** 
** Description..: Control the Si570 Freq. PLL chip over the USB port.
**
** History......: V15.1 02/12/2008: First release of PE0FKO.
**                V15.2 19/12/2008: Change the Si570 code.
**                V15.3 02/01/2009: Add Automatich smooth tune.
**                V15.4 06/01/2009: Add Automatic Band Pass Filter Selection.
**                V15.5 14/01/2009: Add the Smooth tune and band pass filter 
**                                  to the "Set freq by Si570 registers" command.
**                V15.6 17/01/2009: Bug fix, no connection on boot from PC.
**                                  Used a FreqSmooth so the returned freq is
**                                  the real freq and not the smooth center freq.
**                V15.7 22/01/2009: Source change. Upgrade ObDev to 20081022.
**                                  FreqSmoothTune variable removed from eeprom.
**                                  Test errors in i2c code changed. 
**                                  Add cmd 0x00, return firmware version number.
**                                  Add cmd 0x20, Write Si570 register
**                                  Add cmd 0x0F, Reset by Watchdog
**                V15.8 10/02/2009: CalcFreqFromRegSi570() will use the fixed
**                                  xtal freq of 114.285 MHz. Change static 
**                                  variables to make some more free rom space.
**                V15.9 17/02/2009: Disable I/O functions in case the ABPF is enabled.
**               V15.10 18/03/2009: LO frequency subtract and multiply.
**                                  Add cmd 0x31, Write the frequency subtract multiply to the eeprom
**                                  Add cmd 0x39, Return the frequency subtract multiply
**                                  Check if the DCO freq is lower than the Si570 max.
**                                  Include some .c files, it is smaller in size.
**                                  Move some static variables to register, smaller code size.
**                                  Add support for the CW Key_2 in command 0x50 & 0x51.
**                                  CW Key always return open if ABPF is enabled (command 0x50 & 0x51)
**               V15.11 27/07/2009: BUG in the CalcFreqMulAdd() with a negative subtract value.
**                                  Change the SetFreq() so that the filter table is set and 
**                                  after it the subtract multiply is done! (changed in order)
**                                  Changed the SetFreq() so that cmd 0x3a will return the requested
**                                  freq and not the Si570 freq. 
**               V15.12 28/08/2009: Added the IBPF settings. Every band, selected with the Filter
**                                  cross-over table, holds its own offset/multiply and filter number.
**                                  The command 0x41 will return the old I2C address, it only accept
**                                  I2C addresses if Index is zero.
**                                  Change of the USB Serial number is possible for the last char of 
**                                  that string "PE0FKO-0". The "0" can be changed with command 0x43.
**               V15.13 15/06/2010: Bug fix for the filter / band selection in DeviceSi570.c
**                                  Added compiler option for the Si570 chip grade B & C selection.
**                                  Delay 100ms added before the USB enumeration to stabilize the electric part.
**               V15.14 15/12/2010: Added Si570 chip Grade, DCO parameter and correct the si570 
**                                  divider selecttion. Temperature raw value.
**               V15.15 10/12/2011: Changes made necessary for the new Si570 chip from SiLabs.
**                                  The new chip version with 7ppm temperature stability did change the
**                                  Index of the RFREQ registers from 7 to 13. Also a new function to
**                                  freeze the RFREQ when updating new data to the RFREQ (Freeze-M).
**                                  The firmware can auto-detect the new Si570 chip and use the correct
**                                  RFREQ index. The function CMD_SET_SI570_GRADE (0x44) is extended to
**                                  support the change of RFREQ index.
**                                  Also removed some global register variables to normal ram.
**
**************************************************************************

Compiler: WinAVR-20071221
Chip: ATtiny45 (4Kb prom)
V14		3866 bytes (94.4% Full)
V15.1	3856 bytes (94.1% Full)
V15.2	3482 bytes (85.0% Full)
V15.3	3892 bytes (95.0% Full)
V15.4	3918 bytes (95.7% Full)
V15.5	4044 bytes (98.7% Full)
V15.6	4072 bytes (99.4% Full)
V15.7	4090 bytes (99.9% Full)
V15.8	3984 bytes (97.3% Full)
V15.9	3984 bytes (97.3% Full)
V15.10	4018 bytes (98.1% Full)
V15.11	4094 bytes (100.% Full)
V15.12	5112 bytes (62.4% Full), ATtiny85, WinAVR-20090313, vusb-20090822
V15.13	4558 bytes (55.6% Full), ATtiny85, WinAVR-20100110, vusb-20090822
V15.14	4712 bytes (57.5% Full), ATtiny85, WinAVR-20100110, vusb-20100715
V15.15	4902 bytes (59.8% Full), ATtiny85, WinAVR-20100110, vusb-20100715


Fuse bit information:
Fuse high byte:
0xdd = 1 1 0 1   1 1 0 1     RSTDISBL disabled (SPI programming can be done)
0x5d = 0 1 0 1   1 1 0 1     RSTDISBL enabled (PB5 can be used as I/O pin)
       ^ ^ ^ ^   ^ \-+-/ 
       | | | |   |   +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V)
       | | | |   +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved)
       | | | +-------------- WDTON (watchdog timer always on -> disable)
       | | +---------------- SPIEN (enable serial programming -> enabled)
       | +------------------ DWEN (debug wire enable)
       +-------------------- RSTDISBL (disable external reset -> disabled)

Fuse low byte:
0xe1 = 1 1 1 0   0 0 0 1
       ^ ^ \+/   \--+--/
       | |  |       +------- CKSEL 3..0 (clock selection -> HF PLL)
       | |  +--------------- SUT 1..0 (BOD enabled, fast rising power)
       | +------------------ CKOUT (clock output on CKOUT pin -> disabled)
       +-------------------- CKDIV8 (divide clock by 8 -> don't divide) 


Modifications by Fred Krom, PE0FKO at Nov 2008
- Hang on no pull up of SCL line i2c to Si570 (or power down of Si590 in SR-V90)
- Compiler (WinAVR-20071221) optimized the i2c delay loop a way!
- Calculating the Si570 registers from a given frequency, returns a HIGH HS_DIV value
- Source cleanup and split in deferent files.
- Remove many debug USB command calls!
- Version usbdrv-20081022
- Add command 0x31, write only the Si570 registers (change freq max 3500ppm)
- Change the Si570 register calculation and now use the full 38 bits of the chip!
  Is is accurate, fast and small code! It cost only 350us (old 2ms) to calculate the new registers.
- Add command 0x3d, Read the actual used xtal frequency (4 bytes, 24 bits fraction, 8.24 bits)
- Add the "automatic smooth tune" functionality.
- Add the I/O function command 0x15
- Add the commands 0x34, 0x35, 0x3A, 0x3B, 0x3C, 0x3D
- Add the I/O function command 0x16
- Add read / write Filter cross over points 0x17
- Many code optimalization to make the small code.
- Calculation of the freq from the Si570 registers and call 0x32, command 0x30


Implemented functions:
----------------------

V15.10
+----+---+---+---+-----------------------------------------------------
|Cmd |SQA|FKO| IO| Function
+0x--+---+---+---+-----------------------------------------------------
| 00 | * |   | I | Echo value variable
| 00 |   | * | I | Get Firmware version number
| 01 | * | * | I | [DO NOT USE] set port directions
| 02 | * | * | I | [DO NOT USE] read ports
| 03 | * | * | I | [DO NOT USE] read port states 
| 04 | * | * | I | [DO NOT USE] set ports
| 05 | * |   | I | [DO NOT USE] send I2C start sequence
| 06 | * |   | I | [DO NOT USE] send I2C stop sequence
| 07 | * |   | I | [DO NOT USE] send byte to I2C
| 08 | * |   | I | [DO NOT USE] send word to I2C
| 09 | * |   | I | [DO NOT USE] send dword to I2C
| 0A | * |   | I | [DO NOT USE] send word to I2C with start and stop sequence
| 0B | * |   | I | [DO NOT USE] receive word from I2C with start and stop sequence
| 0C | * |   | I | [DO NOT USE] modify I2C clock
| 0D |   |   | I | [DO NOT USE] read OSCCAL to "value"
| 0E |   |   | I | [DO NOT USE] Write "value" to OSCCAL
| 0F | * | * | I | [DO NOT USE] Reset by Watchdog
| 10 | * |   | I | [DO NOT USE] EEPROM write byte value=address, index=data
| 11 | * |   | I | [DO NOT USE] EEPROM read byte "value"=address
| 13 |   |   | I | [DO NOT USE] return usb device address
| 15 |   | * | I | Set IO port with mask and data bytes, and perform cmd 0x16
| 16 |   | * | I | Return the I/O pin value
| 17 |   | * | I | Read the Filter cross over points and set one point
| 18 |   | * | I | Set the RX Band Pass Filter Address for one band: 0..3
| 19 |   | * | I | Read the RX Band Pass Filter Address for one band: 0..3
| 1A |   |   | I | Set the TX Low Pass Filter Address for one band: 0..7 (MOBO)
| 1B |   |   | I | Read the TX Low Pass Filter Address for one band: 0..7 (MOBO)
| 20 | * | * | I | Write byte to Si570 register
| 21 | * |   | I | [DO NOT USE] SI570: read byte to register index (Use command 0x3F)
| 22 | * |   | I | [DO NOT USE] SI570: freeze NCO (Use command 0x20)
| 23 | * |   | I | [DO NOT USE] SI570: unfreeze NCO (Use command 0x20)
| 30 | * | * | O | Set frequency by register and load Si570
| 31 |   | * | O | Write the frequency subtract multiply to the eeprom
| 32 | * | * | O | Set frequency by value and load Si570
| 33 | * | * | O | write new crystal frequency to EEPROM and use it.
| 34 |   | * | O | Write new startup frequency to eeprom
| 35 |   | * | O | Write new smooth tune to eeprom and use it.
| 39 |   | * | I | Return the frequency subtract multiply
| 3A |   | * | I | Return running frequency
| 3B |   | * | I | Return smooth tune ppm value
| 3C |   | * | I | Return the startup frequency
| 3D |   | * | I | Return the XTal frequency
| 3E |   |   | I | [DEBUG] read out calculated frequency control registers
| 3F | * | * | I | Read out frequency control registers
| 40 | * | * | I | Return I2C transmission error status
| 41 | * |   | I | [DO NOT USE] set/reset init freq status
| 41 |   | * | I | Set the new i2c address.
| 42 |   | * | I | CPU Temperaure
| 43 |   | * | I | Change USB SerialNumber ID
| 44 |   | * | I | Change the Si570 chip Grade (A,B,C) and the RFREQ index.
| 50 | * | * | I | Set USR_P1 and get cw-key status
| 51 | * | * | I | Read SDA and CW key level simultaneously


Commands:
---------
All the command are working with the "usb_control_msg" command from the LibUSB open source project.
I'm using "libusb-win32-device-bin-0.1.12.1" from http://sourceforge.net/projects/libusb-win32/

To use the library include the header file ./include/usb.h in your project and add the 
library ./lib/*/libusb.lib for your linker.

Open the device with usb_open(...) with the VID & PID to get a device handle.

  int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
                      int value, int index, char *bytes, int size,
                      int timeout);

    requesttype:    Data In or OUT command (table IO value)
        I = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN
        O = USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT

    request: The command number.
    value:   Word parameter 0
    index:   Word parameter 1
    bytes:   Array data send to the device (OUT) or from the device (IN)
    size:    length in bytes of the "bytes" array.


In case of a unknow command the firmware will return a 1 (one) if there is a bytes array specified it 
returns the byte 255.


In the next examples I will use two subroutines that will call the usb_control_msg function, it make's 
the examples more readable:

int usbCtrlMsgIN(int request, int value, int index, char *bytes, int size)
{
  return usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
                         request, value, index, bytes, size, 500);
}

int usbCtrlMsgOUT(int request, int value, int index, char *bytes, int size)
{
  return usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
                         request, value, index, bytes, size, 500);
}




Command 0x00:
-------------
This call will return the version number of the firmware. The high byte is the version major and the
low byte the version minor number.

It is a bid tricky for the previous versions because they used a "word echo command" on command 0x00.
If the call will be done with the "value" parameter is set to 0x0E00 it will return version 14.0 for the
original DG8SAQ software. (Also my previous software will return the version 14.0, the owner had to
upgrade or not use it). There is also a other way to check the type of software, use the USB Version 
string for that.

Code sample:
    uint16_t version;
    r = usbCtrlMsgIN(0x00, 0x0E00, 0, &version, sizeof(version));
	// if the return value is 2, the variable version will give the major and minor
	// version number in the high and low byte.

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x00
    value:           0x0E00
    index:           0
    bytes:           Version word variable
    size:            2


Command 0x01:
-------------
Set port directions.
Do not use, use I/O function 0x15


Command 0x02:
-------------
Read ports.
Do not use, use I/O function 0x15


Command 0x03:
-------------
Read port states.
Do not use.


Command 0x04:
-------------
Set ports.
In case of the enabled ABPF no change of I/O will be done.
Do not use, use I/O function 0x15


Command 0x0F:
-------------
Restart the board (done by Watchdog timer).

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x0F
    value:           0
    index:           0
    bytes:           NULL
    size:            0


Command 0x15:
-------------
Set the I/O bits of the device. The SoftRock V9 only had two I/O lines, bit0 and bit1.
It also returned the I/O value (like command 0x16).

There are two values for every I/O bit, the data direction and data bits.
+-----+------+----------------------
| DDR | DATA | PIN Function
+-----+------+----------------------
|  0  |   0  | input
|  0  |   1  | input internal pullup
|  1  |   0  | output 0
|  1  |   1  | output 1
+-----+------+----------------------

In case of the enabled ABPF no change of I/O will be done.

Code sample:
    uint16_t INP;
    r = usbCtrlMsgIN(0x15, 0x02, 0x02, &INP, sizeof(INP));
    // Set P2 to output and one!
    // Use P1 as input, no internal pull up R enabled.
    // Read the input in array INP[], only bit0 and bit1 used by this hardware.

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x15
    value:           Data Direction Register
    index:           Data register
    bytes:           PIN status (returned)
    size:            2


Command 0x16:
-------------
Get the I/O values in the returned word, the SoftRock V9 only had two I/O lines, bit0 and bit1.

Code sample:
    uint16_t INP;
    r = usbCtrlMsgIN(0x16, 0, 0, &INP, sizeof(INP));
    // Read the input word INP, only bit0 and bit1 used by SoftRock V9 hardware.

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x16
    value:           0
    index:           0
    bytes:           PIN status (returned)
    size:            2


Command 0x17:
-------------
Read the Filter cross over points and set one point.

This command can control 2 banks of filters.  Typically the first bank is the Rx and Tx BPF
used in the QSD and QSE stages.  The second bank is the Tx LPF between the PA and the antenna
output.  The # of crossover points of the two banks of filters can be different.  For example,
the first bank is usually 4 bands (160m, 80/40m, 30/17/20m, 15/12/10m) as in Softrock v6.3 and
v9.0.  The second bank is usually 6 bands but can go up to 7, 8, 12 or even 16!

The index is used to specify the particular filter crossover point.  The index of the 1st bank
starts from 0, and ends at the last crossover point.  For example, if there are 4 bands, then
there will be 3 crossover points: 0, 1, and 2.  Index 3 is used as a boolean flag, specifying
whether this filter bank is enabled or disabled (for automatic band pass filter ABPF function).

The index of the 2nd filter bank starts from 256, and ends at the last crossover point.  For
example, if there are 6 LPF's, then there will be 5 crossover points, with index 256, 257, 258,
259, and 260.  index 261 is used as a boolean flag, specifying whether this filter bank is
enabled or disabled (for automatic switching).  If "disabled", it usually means the filter is
set for "all pass" or bypassed.

The first call to this command should be used to find out how many crossover points there are.
Call with an index of 255 for the 1st filter bank, and an index of 256+255 for the 2nd filter
bank.

  filter_number_of_bytes = usbCtrlMsgIN(0x17, 0, 255, FilterCrossOver, sizeof(FilterCrossOver));

If there are 4 filters (3 crossover points), then the filter_number_of_bytes returned will be 8.
(Each crossover point is 2 bytes.  Thus there will be 6 bytes.  Following that another 2 bytes will
be for the boolean flag, making a total of 8).

If ther are 6 filters (5 crossover points), there filter_number_of_bytes returned will be 12.

Subsequent calls to this command can then be used to:

1.  set one of the filter crossover points by specifying the index
2.  enable/disable the filter bank by specifying the last index (for the boolean flag)
3.  read the cross over points only - all of them of one bank at once, by specifying 255 (1st bank)
    or 256+255 (2nd bank).

(Note that in actions 1 and 2 above, the cross over points are also read out after the completion
of the action.)

The data format of the crossover points is a 11.5 bits in MHz, that gives a resolution of 1/32 MHz.
The last data entry is a boolean flag to enable or disable the filter bank.

Code sample:
   uint16_t FilterCrossOver[16];        // allocate enough space for up to 16 filters
   unsigned int filter_number_of_bytes;

  // first find out how may cross over points there are for the 1st bank, use 255 for index
  filter_number_of_bytes = usbCtrlMsgIN(0x17, 0, 255, FilterCrossOver, sizeof(FilterCrossOver));

  // Specify filter cross over point for a softrock that divide the LO by 4!
  // And read the points back from the device in the last call.
  if (filter_number_of_bytes == 8)  // 3 crossover points and one flag, so set them up
  {
	FilterCrossOver[0] = 4.1 * 4.0 * (1<<5);
	FilterCrossOver[1] = 8.0 * 4.0 * (1<<5);
	FilterCrossOver[2] = 16. * 4.0 * (1<<5);
	FilterCrossOver[3] = true;        // Enable

	usbCtrlMsgIN(0x17, FilterCrossOver[0], 0, NULL, 0);
	usbCtrlMsgIN(0x17, FilterCrossOver[1], 1, NULL, 0);
	usbCtrlMsgIN(0x17, FilterCrossOver[2], 2, NULL, 0);
	usbCtrlMsgIN(0x17, FilterCrossOver[3], 3, FilterCrossOver, sizeof(FilterCrossOver));
  }


Parameters: Setting one of the points
   requesttype:    USB_ENDPOINT_IN
   request:         0x17
   value:           FilterCrossOver[i]   i being the index of the particular cross over point
   index:           index of the 'value' filter point.
   bytes:           Array of up to 16 16bits integers for the filter points.
   size:            filter_number_of_bytes

Parameters: Enable / disable the filter
   requesttype:    USB_ENDPOINT_IN
   request:         0x17
   value:           0 (disable) or 1 (enable)
   index:           index of 1 plus the last crossover point
   bytes:           Array of up to 16 16bits integers for the filter points.
   size:            filter_number_of_bytes


Command 0x18:
-------------
Set the RX Band Pass Filter Address for one band: 0..3

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x18
    value:           Filter for the band
    index:           Band number (0..3)
    bytes:           pointer 4 byte array, Band2Filter table
    size:            4


Command 0x19:
-------------
Read the RX Band Pass Filter Address for one band: 0..3

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x19
    value:           0
    index:           0
    bytes:           pointer 4 byte array, Band2Filter table
    size:            4


Command 0x1A:
-------------
Set the TX Low Pass Filter Address for one band: 0..7 (MOBO)
Not implemented


Command 0x1B:
-------------
Read the TX Low Pass Filter Address for one band: 0..7 (MOBO)
Not implemented


Command 0x20:
-------------
Write one byte to a Si570 register. Return value is the i2c error boolean in the buffer array.

Code sample:
	// Si570 RECALL function
	uint8_t i2cError;
    r = usbCtrlMsgIN(0x20, 0x55 | (135<<8), 0x01, &i2cError, 1);
	if (r == 1 && i2cError == 0)
		// OK

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x20
    value:           I2C Address low byte (only for the DG8SAQ firmware)
                     Si570 register high byte
    index:           Register value low byte
    bytes:           NULL
    size:            0


Command 0x30:
-------------
Set the oscillator frequency by Si570 register. The real frequency will be 
calculated by the firmware and the called command 0x32

Default:    None

Parameters:
    requesttype:    USB_ENDPOINT_OUT
    request:         0x30
    value:           I2C Address (only for the DG8SAQ firmware), 0
    index:           7 (only for the DG8SAQ firmware), 0
    bytes:           pointer 48 bits register
    size:            6


Command 0x31:
-------------
Write the frequency subtract, multiply value's to the eeprom and use it.

The real frequency is the input frequnecy minus the subtract value times the multiply value.
Si570_F = (Finput - subtract) * multiply


Default:    None

Parameters:
    requesttype:    USB_ENDPOINT_OUT
    request:         0x31
    value:           0
    index:           0
    bytes:           pointer 2 * 32 bits interger
    size:            8

Code sample:
	double sub, mul;
    uint32_t iSM[2];

	sub = 135.0;
	mul = 4.0;

	iSM[0] = (uint32_t)( sub * (1UL << 21) );
	iSM[1] = (uint32_t)( mul * (1UL << 21) );

    r = usbCtrlMsgOUT(0x31, 0, 0, (char *)iSM, sizeof(iSM));
    if (r != sizeof(iSM)) Error



Command 0x32:
-------------
Set the oscillator frequency by value. The frequency is formatted in MHz
as 11.21 bits value. 
The "automatic band pass filter selection", "smooth tune", "one side calibration" and
the "frequency subtract multiply" are all done in this function. (if anabled in the firmware)

Default:    None

Parameters:
    requesttype:    USB_ENDPOINT_OUT
    request:         0x32
    value:           0
    index:           0
    bytes:           pointer 32 bits integer
    size:            4

Code sample:
    uint32_t iFreq;
    double   dFreq;

    dFreq = 30.123456; // MHz
    iFreq = (uint32_t)( dFreq * (1UL << 21) )
    r = usbCtrlMsgOUT(0x32, 0, 0, (char *)&iFreq, sizeof(iFreq));
    if (r < 0) Error


Command 0x33:
-------------
Write new crystal frequency to EEPROM and use it. It can be changed to calibrate the device.
The frequency is formatted in MHz as a 8.24 bits value.

Default:    114.285 MHz

Parameters:
    requesttype:    USB_ENDPOINT_OUT
    request:         0x33
    value:           0
    index:           0
    bytes:           pointer 32 bits integer
    size:            4

Code sample:
    uint32_t iXtalFreq;
    double   dXtalFreq;

    dXtalFreq = 114.281;
    iXtalFreq = (uint32_t)( dXtalFreq * (1UL<<24) )
    r = usbCtrlMsgOUT(0x33, 0, 0, (char *)&iXtalFreq, sizeof(iXtalFreq));
    if (r < 0) Error


Command 0x34:
-------------
Write new startup frequency to eeprom. When the device is started it will output
this frequency until a program set an other frequency.
The frequency is formatted in MHz as a 11.21 bits value.

Default:    4 * 7.050 MHz

Parameters:
    requesttype:    USB_ENDPOINT_OUT
    request:         0x34
    value:           0
    index:           0
    bytes:           pointer 32 bits integer
    size:            4

Code sample:
    uint32_t iXtalFreq;
    double   dXtalFreq;

    dFreq = 4.0 * 3.550; // MHz
    iFreq = (uint32_t)( dFreq * (1UL<<24) )
    r = usbCtrlMsgOUT(0x34, 0, 0, (char *)&iFreq, sizeof(iFreq));
    if (r < 0) Error


Command 0x35:
-------------
Write new smooth tune to eeprom and use it.

Default:    3500 PPM

Parameters:
    requesttype:    USB_ENDPOINT_OUT
    request:         0x35
    value:           0
    index:           0
    bytes:           pointer 16 bits integer
    size:            2

Code sample:
    uint16_t Smooth;
    Smooth = 3400;
    r = usbCtrlMsgOUT(0x35, 0, 0, (char *)&Smooth, sizeof(Smooth));
    if (r < 0) Error


Command 0x39:
-------------
Return the frequency subtract multiply values.
V15.12: The index is tha band for with the values are working.

Default:    subtract = 0.0, multiply = 1.0

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x39
    value:           0
    index:           0	or	Index into band
    bytes:           pointer 2 * 32 bits integer
    size:            8

Code sample:
    uint32_t iSM[2];
	double sub, mul;
	uint8_t iBand;

	iBand = 0;
    r = usbCtrlMsgIN(0x39, 0, iBand, (char *)iSM, sizeof(iSM));
    if (r != sizeof(iSM)) Error

	sub = (double)(int32_t)iSM[0] / (1UL << 21); // Signed value
	mul = (double)         iSM[1] / (1UL << 21);


Command 0x3A:
-------------
Return actual frequency of the device.
The frequency is formatted in MHz as a 11.21 bits value.

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x3A
    value:           0
    index:           0
    bytes:           pointer 32 bits integer
    size:            4

Code sample:
    uint32_t iFreq;
    double   dFreq;
    r = usbCtrlMsgIN(0x3A, 0, 0, (char *)&iFreq, sizeof(iFreq));
    if (r == 4)
        dFreq = (double)iFreq / (1UL<<21);


Command 0x3B:
-------------
Return the "Smooth tune" PPM (pulse per MHz) of the device.
The value is default 3500 (from data sheet) and can be changed. I do not know what 
happened with the chip if it is out of range (>3500).
If the value is set to zero it will disable the "Automatic Smooth tune" function.

Default:    3500 PPM

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x3B
    value:           0
    index:           0
    bytes:           pointer 16 bits integer
    size:            2

Code sample:
    uint16_t Smooth;
    r = usbCtrlMsgIN(0x3B, 0, 0, (char *)&Smooth, sizeof(Smooth));
    if (r == 2) ...


Command 0x3C:
-------------
Return device startup frequency.
The frequency is formatted in MHz as a 11.21 bits value.

Default:    4 * 7.050 MHz

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x3C
    value:           0
    index:           0
    bytes:           pointer 32 bits integer
    size:            4

Code sample:
    uint32_t iFreq;
    double   dFreq;
    r = usbCtrlMsgIN(0x3C, 0, 0, (char *)&iFreq, sizeof(iFreq));
    if (r == 4)
        dFreq = (double)iFreq / (1UL<<21);


Command 0x3D:
-------------
Return device crystal frequency.
The frequency is formatted in MHz as a 8.24 bits value.

Default:    114.285 MHz

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x3D
    value:           0
    index:           0
    bytes:           pointer 32 bits integer
    size:            4

Code sample:
    uint32_t iFreqXtal;
    double   dFreqXtal;
    r = usbCtrlMsgIN(0x3D, 0, 0, (char *)&iFreqXtal, sizeof(iFreqXtal));
    if (r == 4)
        dFreqXtal = (double)iFreqXtal / (1UL<<24);


Command 0x3F:
-------------
Return the Si570 frequency control registers (reg 7:12 or reg 13:18). If there are I2C errors
the return length is 0.

Default:    None

Parameters:
    requesttype:     USB_ENDPOINT_IN
    request:         0x3F
    value:           Not used
    index:           Byte index in Si570 registers, 0 = default index other the start index (read 6 bytes).
    bytes:           pointer 6 byte register array
    size:            6


Command 0x41:
-------------
Set a new I2C address for the Si570 chip and return the old I2C address.
If the value is not zero the I2C address will be writen to eeprom and the old value is always returned, 
The function can also be used to reset the device to "factory default" by writing the
value 255. After a restart the device will initialize to all the default values.

Default:    0x55 (85 decimal)

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x41
    value:           I2C address or 255 [byte]
    index:           0
    bytes:           pointer 1 byte I2C address
    size:            1


Command 0x42:
-------------
Get CPU Temperaure from the attiny[48]5

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x42
    value:           0
    index:           0
    bytes:           pointer 2 bytes ADC temperatur value
    size:            2


Command 0x43:
-------------
Set and return the USB SerialNumber ID. The USB SerialNumber "PE0FKO-0" can be changed only for the
last char "0". If the value is not zero the ID char will be writen to eeprom and the old value is always returned, 

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x43
    value:           New ID char (>0) [byte]
    index:           0
    bytes:           pointer 1 byte ID address
    size:            1


Command 0x44:
-------------
Change and get the Si570 chip Grade, RFREQ register index and DCO min / max value. The grade can
be a number from 0 (no change), 1 (grade A), 2 (grade B), 3 (grade C, default). The grade zero will
not change the grade.
When specifying the chip grade it also set the RFREQ register index. The index must
be changed when using the new Si570 7ppm (temperature) chip. There are three value (0, 7 or 13)
possible, the value 0 is a auto-detect function.
Also the freeze of the frequency when updating the RFREQ register (only new Si570) can be
specified with this function.

The divider restrictions for the 3 Si57x speed grades or frequency grades are as follows
- Grade A covers 10 to 945 MHz, 970 to 1134 MHz, and 1213 to 1417.5 MHz. Speed grade A
  device have no divider restrictions.
- Grade B covers 10 to 810 MHz. Speed grade B devices disable the output in the following
  N1*HS_DIV settings: 1*4, 1*5
- Grade C covers 10 to 280 MHz. Speed grade C devices disable the output in the following
  N1*HS_DIV settings: 1*4, 1*5, 1*6, 1*7, 1*11, 2*4, 2*5, 2*6, 2*7, 2*9, 4*4

Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x44
    value:           Si570 chip grade (0..3) in low byte, RFREQ Index (0,7,13) in high byte, Freeze-M in bit 15.
    index:           DCO min if high byte value is zero, DCO max if high byte value is not zero
    bytes:           pointer 5 byte grade address
    size:            5


Command 0x50:
-------------
Set PTT (PB4) I/O line and read CW key level from the PB5 (CW Key_1) and PB1 (CW Key_2).
In case of the enabled ABPF no change of PTT I/O line will be done and no read of the CW key's are
done. The command will return (in case of enabled ABPF) for both CW key's a open status (bits are 1).
The returnd bit value is bit 5 (0x20) for CW key_1 and bit 1 (0x02) for CW key_2, the other bits are zero.


Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x50
    value:           Output bool to user output PTT
    index:           0
    bytes:           pointer to 1 byte variable CW Key's
    size:            1


Command 0x51:
-------------
Read CW key level from the PB5 (CW Key_1) and PB1 (CW Key_2).
In case of the enabled ABPF no read of the CW key's are done. The command will return for both CW key's 
a open status (bits are 1).
The returnd bit value is bit 5 (0x20) for CW key_1 and bit 1 (0x02) for CW key_2, the other bits are zero.


Parameters:
    requesttype:    USB_ENDPOINT_IN
    request:         0x51
    value:           0
    index:           0
    bytes:           pointer to 1 byte variable CW Key's
    size:            1


EOF

 

Disclaimer: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

F.W. Krom


File last modified on Wednesday, 06-Oct-2021 09:57:27 CEST
My BitCoin address: 1MqQWXdaBAmYFNqXnQLd5cxG6KkvLj9LPK
eXTReMe Tracker