2626 * 2. Faking some Pthread calls using Win-SDK function.
2727 * 3. Changed the code-style using Astyle.
2828 *
29- * Hence nothing here depends on the libusb library.
29+ * So nothing here depends on the libusb library.
3030 */
3131#include <windows.h>
3232#include <winusb.h>
3838#include <stdbool.h>
3939#include <stdio.h>
4040
41- #include "RTLSDR/ rtl-sdr.h"
42- #include "RTLSDR/ tuner_e4k.h"
43- #include "RTLSDR/ tuner_fc001x.h"
44- #include "RTLSDR/ tuner_fc2580.h"
45- #include "RTLSDR/ tuner_r82xx.h"
46- #include "RTLSDR/ version.h"
47- #include "RTLSDR/ trace.h"
41+ #include "rtl-sdr.h"
42+ #include "tuner_e4k.h"
43+ #include "tuner_fc001x.h"
44+ #include "tuner_fc2580.h"
45+ #include "tuner_r82xx.h"
46+ #include "version.h"
47+ #include "trace.h"
4848
4949#define WINUSB_REQUEST_TYPE_VENDOR (0x02 << 5)
5050#define WINUSB_ENDPOINT_IN 0x80
@@ -185,6 +185,11 @@ struct rtlsdr_dev {
185185 */
186186 CRITICAL_SECTION cs_mutex ;
187187
188+ /* GPIO stuff
189+ */
190+ uint32_t gpio_state_known ; /* bitmask over pins 0 .. 7 */
191+ uint32_t gpio_state ; /* bitmask over pins 0 .. 7: = 0 == write, 1 == read */
192+
188193 /* status */
189194 int rc_active ;
190195 int opening ;
@@ -1079,16 +1084,83 @@ static int rtlsdr_demod_write_reg_mask (rtlsdr_dev_t *dev, uint8_t page, uint16_
10791084 return rtlsdr_demod_write_reg (dev , page , addr , (uint16_t ) val , 1 );
10801085}
10811086
1082- void rtlsdr_set_gpio_bit (rtlsdr_dev_t * dev , uint8_t gpio , int val )
1087+ int rtlsdr_set_gpio_bit (rtlsdr_dev_t * dev , uint8_t gpio , int val )
1088+ {
1089+ return rtlsdr_write_reg_mask (dev , SYSB , GPO , val << gpio , 1 << gpio );
1090+ }
1091+
1092+ int rtlsdr_set_gpio_byte (rtlsdr_dev_t * dev , int val )
10831093{
1084- rtlsdr_write_reg_mask (dev , SYSB , GPO , val << gpio , 1 << gpio );
1094+ int retval = rtlsdr_write_reg (dev , SYSB , GPO , val , 1 );
1095+ return retval ;
1096+ }
1097+
1098+ int rtlsdr_set_gpio_input (rtlsdr_dev_t * dev , uint8_t gpio )
1099+ {
1100+ int r , retval = 0 ;
1101+
1102+ gpio = 1 << gpio ;
1103+
1104+ /* state: bitmask over pins 0 .. 7: = 0 == write, 1 == read
1105+ */
1106+ if (!(dev -> gpio_state_known & gpio ) || !(dev -> gpio_state & gpio ))
1107+ {
1108+ r = rtlsdr_read_reg (dev , SYSB , GPD );
1109+ retval = rtlsdr_write_reg (dev , SYSB , GPD , r | gpio , 1 );
1110+ if (retval < 0 )
1111+ return retval ;
1112+
1113+ r = rtlsdr_read_reg (dev , SYSB , GPOE );
1114+ retval = rtlsdr_write_reg (dev , SYSB , GPOE , r & ~gpio , 1 );
1115+ if (retval < 0 )
1116+ return retval ;
1117+
1118+ dev -> gpio_state_known |= gpio ;
1119+ dev -> gpio_state |= ((uint32_t )gpio );
1120+ }
1121+ return retval ;
10851122}
10861123
1087- static void rtlsdr_set_gpio_output (rtlsdr_dev_t * dev , uint8_t gpio )
1124+ int rtlsdr_set_gpio_output (rtlsdr_dev_t * dev , uint8_t gpio )
10881125{
1126+ int r ;
1127+
10891128 gpio = 1 << gpio ;
1090- rtlsdr_write_reg_mask (dev , SYSB , GPD , ~gpio , gpio );
1091- rtlsdr_write_reg_mask (dev , SYSB , GPOE , gpio , gpio );
1129+ r = rtlsdr_write_reg_mask (dev , SYSB , GPD , ~gpio , gpio );
1130+ r |= rtlsdr_write_reg_mask (dev , SYSB , GPOE , gpio , gpio );
1131+
1132+ dev -> gpio_state_known |= gpio ;
1133+ dev -> gpio_state &= ~((uint32_t )gpio );
1134+ return (r );
1135+ }
1136+
1137+ /*
1138+ * These extra GPIO functions are not really needed.
1139+ * They are implemented solely to make the code more similar
1140+ * to other RTLSDR libraries.
1141+ */
1142+ int rtlsdr_set_gpio_status (rtlsdr_dev_t * dev , int * status )
1143+ {
1144+ int r = rtlsdr_read_reg (dev , SYSB , GPD );
1145+
1146+ * status = r ;
1147+ return (0 ); /* no way to determine error with rtlsdr_read_reg() for now! */
1148+ }
1149+
1150+ int rtlsdr_get_gpio_bit (rtlsdr_dev_t * dev , uint8_t gpio , int * val )
1151+ {
1152+ uint16_t r ;
1153+
1154+ gpio = 1 << gpio ;
1155+ r = rtlsdr_read_reg (dev , SYSB , GPI );
1156+ * val = (r & gpio ) ? 1 : 0 ;
1157+ return (0 ); /* no way to determine error with rtlsdr_read_reg() for now! */
1158+ }
1159+
1160+ int rtlsdr_get_gpio_byte (rtlsdr_dev_t * dev , int * val )
1161+ {
1162+ * val = rtlsdr_read_reg (dev , SYSB , GPI );
1163+ return (0 ); /* no way to determine error with rtlsdr_read_reg() for now! */
10921164}
10931165
10941166static int rtlsdr_set_i2c_repeater (rtlsdr_dev_t * dev , int on )
@@ -1939,7 +2011,7 @@ int rtlsdr_set_sample_rate (rtlsdr_dev_t *dev, uint32_t samp_rate)
19392011 real_rate = (dev -> rtl_xtal * TWO_POW (22 )) / real_rsamp_ratio ;
19402012
19412013 if ((double )samp_rate != real_rate )
1942- RTL_TRACE (1 , "Exact sample rate is: %f Hz\n" , real_rate );
2014+ RTL_TRACE (1 , "Exact sample rate is: %.6f Hz\n" , real_rate );
19432015
19442016 dev -> rate = (uint32_t ) real_rate ;
19452017
@@ -3270,7 +3342,7 @@ uint32_t rtlsdr_get_version (void)
32703342 ((uint32_t )RTLSDR_MICRO << 8 ) | (uint32_t )RTLSDR_NANO ;
32713343}
32723344
3273- static void softagc_control_worker (void * arg )
3345+ static unsigned int __stdcall softagc_control_worker (void * arg )
32743346{
32753347 rtlsdr_dev_t * dev = (rtlsdr_dev_t * ) arg ;
32763348 struct softagc_state * agc = & dev -> softagc ;
@@ -3285,6 +3357,8 @@ static void softagc_control_worker (void *arg)
32853357 else
32863358 Sleep (10 );
32873359 }
3360+ _endthreadex (0 );
3361+ return (0 );
32883362}
32893363
32903364static void softagc_init (rtlsdr_dev_t * dev )
@@ -3302,16 +3376,17 @@ static void softagc_init (rtlsdr_dev_t *dev)
33023376 agc -> softAgcMode = SOFTAGC_OFF ;
33033377
33043378 /* Create thread */
3305- agc -> command_thread = _beginthread (softagc_control_worker , 0 , dev );
3306- RTL_TRACE (1 , "%s(): agc->command_thread: %zu\n" , __FUNCTION__ , agc -> command_thread );
3307- if (agc -> command_thread == -1 )
3308- agc -> command_thread = 0 ;
3379+ agc -> command_thread = _beginthreadex (NULL , 0 , softagc_control_worker , dev , 0 , NULL );
3380+
3381+ RTL_TRACE (1 , "%s(): thread-handle: %zu\n" , __FUNCTION__ , agc -> command_thread );
33093382}
33103383
33113384static void softagc_close (rtlsdr_dev_t * dev )
33123385{
33133386 struct softagc_state * agc = & dev -> softagc ;
33143387
3388+ EnterCriticalSection (& dev -> cs_mutex );
3389+
33153390 agc -> softAgcMode = SOFTAGC_OFF ;
33163391 agc -> exit_command_thread = 1 ;
33173392 Sleep (50 );
@@ -3324,6 +3399,7 @@ static void softagc_close (rtlsdr_dev_t *dev)
33243399 CloseHandle ((HANDLE )agc -> command_thread );
33253400 agc -> command_thread = 0 ;
33263401 }
3402+ LeaveCriticalSection (& dev -> cs_mutex );
33273403}
33283404
33293405static void softagc (rtlsdr_dev_t * dev , uint8_t * buf , int len )
0 commit comments