newscript ' ######################################################################################## ' Adafruit MCP2221 breakout board ' ' A script written for PlodWare Scripter ' 2025-06-01 ' ######################################################################################## ' ' The Adafruit MCP2221 breakout board has a USB interface and can be ' used by computing devices such as a USB equipped PC running Windows. ' The USB interface of the Adafruit MCP2221 breakout board is supported by ' Microchip Technology Inc. ' ' pwScripter can not, out of the box, speak to a device connected via USB. ' However Microchip Technology Inc. provides a DLL via which pwScripter ' can get access to the breakout board. ' ' I found the dll "mcp2221_dll_um_x64", inside a ZIP file,at ' https://www.microchip.com/en-us/product/MCP2221 ' Also in the ZIP file was the MCP2221 DLL User Guide. ' ' Copy the unmanaged 64 bit DLL to C:\Windows\System32\ ' Actually you do not need to do this IF you place a copy ' of the unmanaged 64 bit DLL in the same folder as the pwScripter excutable! ' ' pwScripter is written in "plain-old C" it is an "unmanaged" application, ' so be sure that the DLL in the "_um_" one! ' ----------------------------------- ' ' There are about 60 functions in the DLL, we shall use ' about 25 of them which will be enough for demonstrating: ' ' getting info about the DLL ' enumerating the connected devices ' accessing a connected device ' getting info about a connected device ' read/writing with I2C ' read/writing with SmBus ' configuring the general purpose (GP) pins ' using GP pins for digital input/output ' using GP pins for analogue input/output ' ----------------------------------- ' ' Please note that the default working voltage for the ' breakout board is 3.3V, controlled by a jumper on the ' underside of the board ' See: https://forums.adafruit.com/viewtopic.php?t=183126 ' ----------------------------------- ' Note: many of the DLL functions return an INT, but in "C" an int is 32 bits. ' In pwS the default is 64 bits, so a "C" int must be converted internally to 64 bits. ' For unsigned values this simple means filling in the upper 32 bits with zeros. ' For signed values we need to fill the upper 32 bits with the SIGN bit of the 32 bit signed value. ' The "signed32" string (the return parameter type) in the following calls to dll.link will ' ensure that the 32 bit SIGN bit is extended to a 64 bit signed integer! ' Note: I have included the "C" language function prototypes for the various ' DLL function that we want to link to, just for information! ' I decided that each exposed DLL function shall have a leading _ in its pwS name ' to help make clear if we are calling a DLL function, or a wrapper around it, or an ordinary pwS function. ' ----------------------------------- FUNCTION MCP_initialiseDLL () ' Create pwScripter wrappers around some (26) of the (~60) functions exposed in the MCP2221 DLL ' most of the function prototype descriptions in this function ' are copy and paste from the MCP2221 DLL User Guide returnValue = ErrorFlag ' do we have a handle to the DLL ' If so we assume that initialisation has already been done. TRY static dim mcpDLL = ErrorFlag END TRY IF (! isError(mcpDLL) ) then ' already initialised EXIT function END if dim mcpDLLfile = "mcp2221_dll_um_x64" mcpDLL = dll.open (mcpDLLfile) IF ( ! mcpDLL ) THEN mcpDLL = ErrorFlag report ( "MCP: Could not open the DLL file: " & mcpDLLfile ) STOP END IF returnValue = mcpDLL ' Dll Driver Links ' int Mcp2221_GetConnectedDevices(unsigned int vid, unsigned int pid, unsigned int *noOfDevs) global dim _MCP_GetConnectedDevices= dll.link(mcpDLL, "Mcp2221_GetConnectedDevices", 3 ,"signed32" ) ' int Mcp2221_GetLibraryVersion(wchar_t* version) global dim _Mcp2221_GetLibraryVersion= dll.link(mcpDLL, "Mcp2221_GetLibraryVersion", 1 ,"signed32" ) ' void* Mcp2221_OpenByIndex(unsigned int VID, unsigned int PID, unsigned int index) global dim _MCP_OpenByIndex= dll.link(mcpDLL, "Mcp2221_OpenByIndex", 3 ,"unsigned" ) ' void* Mcp2221_OpenBySN(unsigned int VID, unsigned int PID, wchar_t * serialNo) global dim _MCP_OpenBySn= dll.link(mcpDLL, "Mcp2221_OpenBySN", 3 ,"unsigned" ) ' int Mcp2221_Close(void *handle) global dim _MCP_Close= dll.link(mcpDLL, "Mcp2221_Close",1,"signed32" ) ' int Mcp2221_GetVidPid(void* handle, unsigned int* vid, unsigned int* pid) global dim _MCP_GetVidPid= dll.link(mcpDLL, "Mcp2221_GetVidPid",3,"signed32" ) ' int Mcp2221_CloseAll() global dim _MCP_CloseALL= dll.link(mcpDLL, "Mcp2221_CloseAll",0,"signed32" ) ' ================================================================================================== ' int Mcp2221_GetGpioSettings(void* handle, unsigned char whichToGet, unsigned char* pinFunctions, ' unsigned char* pinDirections, unsigned char* outputValues) ' Description: Gets the GPIO settings. ' Parameters: ' Inputs: ' (void*) handle - the handle for the device ' (unsigned char) whichToGet - 0 to read Flash settings, >0 to read SRAM (runtime) settings ' Outputs: ' (unsigned char*) pinFunctions - Array containing the values for the pin functions. ' pinFunction[i] will contain the value for pin GPi. ' Possible values: 0 to 3. 0 - GPIO, 1 - Dedicated function, 2 - ' alternate function 0, 3 - alternate function 1, 4 - alternate ' function 2. ' GP0: 0 GPIO GP1: 0 GPIO GP2: 0 GPIO GP3: 0 - GPIO ' 1 SSPND 1 - Clock Out 1 - USBCFG 1 - LED I2C ' 2 - LED UART RX 2 - ADC1 2 - ADC2 2 - ADC3 ' 3 - LED UART TX 3 - DAC1 3 - DAC2 ' 4 - Interrupt detection ' (unsigned char*) pinDirections - Array containing the pin direction of the IO pins. ' 0 - output ' 1 - input ' (unsigned char*) outputValues - Array containing the value present on the output pins. ' 0 - logic low ' 1 - logic high ' Returns: 0 if successful; error code otherwise ' NOTE: all output arrays must have a minimum length of 4. global dim _MCP_GetGpioSettings = dll.link(mcpDLL, "Mcp2221_GetGpioSettings",5,"signed32" ) ' ================================================================================================== ' int Mcp2221_SetGpioSettings(void* handle, unsigned char whichToSet, unsigned char* pinFunctions, ' unsigned char* pinDirections, unsigned char* outputValues) ' Description: Sets the GPIO settings. ' Parameters: ' Inputs: ' (void*) handle - the handle for the device ' (unsigned char) whichToGet - 0 to read Flash settings, >0 to read SRAM (runtime) settings ' Outputs: ' (unsigned char*) pinFunctions - Array containing the values for the pin functions. ' pinFunction[i] will contain the value for pin GP"i. ' Possible values: 0 to 3. 0 - GPIO, 1 - Dedicated function, 2 - ' alternate function 0, 3 - alternate function 1, 4 - alternate ' function 2. ' GP0: 0 GPIO GP1: 0 GPIO GP2: 0 GPIO GP3: 0 - GPIO ' 1 SSPND 1 - Clock Out 1 - USBCFG 1 - LED I2C ' 2 - LED UART RX 2 - ADC1 2 - ADC2 2 - ADC3 ' 3 - LED UART TX 3 - DAC1 3 - DAC2 ' 4 - Interrupt detection ' (unsigned char*) pinDirections - Array containing the pin direction of the IO pins. ' 0 - output ' 1 - input ' (unsigned char*) outputValues - Array containing the value present on the output pins. ' 0 - logic low ' 1 - logic high ' Returns: 0 if successful; error code otherwise ' NOTE: all output arrays must have a minimum length of 4. global dim _MCP_SetGpioSettings = dll.link(mcpDLL, "Mcp2221_SetGpioSettings",5,"signed32" ) ' ================================================================================================== ' SMBus and I2C are very similar ' however the SMBus is limited to 100 kb/s, I2C can go faster ' and if I have understood it correctly, then a ' SmBus read command requires an i2c address AND a command byte ' so in i2c terms it is more like a i2cWrite( i2aAddress, command byte) to the i2c device ' AND THEN i2cRead 'n' byte(s) from the i2c device ' ----------------------------------- ' int Mcp2221_I2cRead(void* handle, unsigned int bytesToRead, unsigned char slaveAddress, ' unsigned char use7bitAddress, unsigned char* i2cRxData) global dim _MCP_I2CRead = dll.link(mcpDLL, "Mcp2221_I2cRead",5,"signed32" ) ' ----------------------------------- ' int Mcp2221_I2cWrite(void* handle, unsigned int bytesToWrite, unsigned char slaveAddress, ' unsigned char use7bitAddress, unsigned char* i2cTxData) ' (void*) handle - The handle for the device. ' (unsigned int) bytesToWrite - the number of bytes to write to the slave. Valid range is ' between 0 and 65535. ' (unsigned char) slaveAddress - 7bit or 8bit I2C slave address, depending on the value of the ' "use7bitAddress" flag.For 8 bit addresses, the R/W LSB of the ' address is set to 0 inside the function. ' (unsigned char) use7bitAddress - if >0 7 bit address will be used for the slave. If 0, 8 bit is used. ' (unsigned char*) i2cTxData - buffer that will contain the data bytes to be sent to the slave. ' Returns: (int) - 0 for success; error code otherwise. ' NOTE: if the "Mcp2221_SetSpeed" function has not been called for the provided handle, the default ' speed of 100kbps will be configured and used. Otherwise, the global dim _MCP_I2CWrite = dll.link(mcpDLL, "Mcp2221_I2cWrite",5,"signed32" ) ' ================================================================================================== global dim _MCP_SmbusReadByte = dll.link(mcpDLL, "Mcp2221_SmbusReadByte",6,"signed32" ) ' returns 0 = success global dim _MCP_SmbusWriteByte = dll.link(mcpDLL, "Mcp2221_SmbusWriteByte",6,"signed32" ) ' returns 0 = success ' ================================================================================================== ' int Mcp2221_SetDacValue(void*handle, unsigned char whichToSet, unsigned char dacValue) ' Description: Sets the DAC value. ' Parameters: ' Inputs: ' (void*) handle - the handle for the device ' (unsigned char) whichToSet - 0 to write Flash settings, >0 to write SRAM (runtime) settings ' (unsigned char) dacValue - The DAC output value. Valid range is between 0 and 31. ' Returns: 0 if successful; error code otherwise global dim _MCP_SetDacValue = dll.link(mcpDLL, "Mcp2221_SetDacValue",3,"signed32" ) ' ================================================================================================== ' int Mcp2221_GetAdcVref(void*handle, unsigned char whichToGet, unsigned char* adcVref) global dim _MCP_GetAdcVref = dll.link(mcpDLL, "Mcp2221_GetAdcVref",3,"signed32" ) ' int Mcp2221_SetAdcVref(void*handle, unsigned char whichToSet, unsigned char adcVref) global dim _MCP_SetAdcVref = dll.link(mcpDLL, "Mcp2221_SetAdcVref",3,"signed32" ) ' ================================================================================================== ' int Mcp2221_GetDacVref(void*handle, unsigned char whichToGet, unsigned char* adcVref) global dim _MCP_GetDacVref = dll.link(mcpDLL, "Mcp2221_GetDacVref",3,"signed32" ) ' int Mcp2221_SetDacVref(void*handle, unsigned char whichToSet, unsigned char adcVref) global dim _MCP_SetDacVref = dll.link(mcpDLL, "Mcp2221_SetDacVref",3,"signed32" ) ' ================================================================================================== ' int Mcp2221_GetGpioValues(void* handle, unsigned char* gpioValues) ' Description: Gets the GPIO pin values. ' Parameters: ' Inputs: ' (void*) handle - the handle for the device ' Outputs: ' (unsigned char*) gpioValues - Array containing the value present on the IO pins. ' 0 - logic low ' 1 - logic high ' 0xEE - GPx not set for GPIO operation ' Returns: 0 if successful; error code otherwise ' NOTE: the output array must have a minimum length of 4. global dim _MCP_GetGpioValues = dll.link(mcpDLL, "Mcp2221_GetGpioValues", 2 ,"signed32" ) ' ================================================================================================== ' int Mcp2221_SetGpioValues(void* handle, unsigned char* gpioValues) ' Description: Sets the runtime GPIO pin values. Sets the runtime GPIO pin directions; flash values ' are not changed. ' Parameters: ' Inputs: ' (void*) handle - the handle for the device ' (unsigned char*) gpioValues - Array containing the value of the output IO pins. ' 0 - logic low ' 1 - logic high ' 0xFF - no change ' Returns: 0 if successful; error code otherwise ' NOTE: the output array must have a minimum length of 4 global dim _MCP_SetGpioValues = dll.link(mcpDLL, "Mcp2221_SetGpioValues", 2 ,"signed32" ) ' ================================================================================================== ' int Mcp2221_GetAdcData(void* handle, unsigned int* adcDataArray) ' Description: Reads the ADC data for all 3 analog pins. ' Parameters: ' Inputs: ' (void*) handle - the handle for the device. ' (unsigned int*) adcDataArray - Array containing the ADC values. Entry 0 will contain the value ' for ADC1, entry 1 - ADC2, entry 2 - ADC3 ' Returns: 0 if successful; error code otherwise ' NOTE: the array must have a minimum length of 3. global dim _MCP_GetAdcData = dll.link(mcpDLL, "Mcp2221_GetAdcData",2,"signed32" ) ' ================================================================================================== ' Dll Device Info Links ' int Mcp2221_GetManufacturerDescriptor(void* handle, wchar_t* manufacturerString) global dim _MCP_GetManufacturerDescriptor= dll.link(mcpDLL, "Mcp2221_GetManufacturerDescriptor", 2, "signed32" ) ' int Mcp2221_GetProductDescriptor(void* handle, wchar_t* manufacturerString) global dim _MCP_GetProductDescriptor= dll.link(mcpDLL, "Mcp2221_GetProductDescriptor", 2, "signed32" ) ' int Mcp2221_GetSerialNumberDescriptor(void* handle, wchar_t* serialNumber) global dim _MCP_GetSerialNumberDescriptor= dll.link(mcpDLL, "Mcp2221_GetSerialNumberDescriptor", 2, "signed32" ) ' int Mcp2221_GetFactorySerialNumber(void* handle, wchar_t* serialNumber) global dim _MCP_GetFactorySerialNumber= dll.link(mcpDLL, "Mcp2221_GetFactorySerialNumber",2,"signed32" ) ' ================================================================================================== ' define global variables global dim MCP_defaultVID = 0x4D8 global dim MCP_defaultPID = 0x0DD global dim mcp_Handle = 0 END Function ' ----------------------------------- FUNCTION MCP_DisplayDLLinfo ( ) dim wchar = wordArray (128) ' used to hold text (wide-char utf-16 16 bits/char) info returned by some DLL function calls report(chr(0x0a) & "MCP DLL/Driver info:-") wchar(0) = 0 _Mcp2221_GetLibraryVersion( wchar ) report ("MCP driver: Factory Serial Number: " & cstr ( wchar ) ) dim nbrDevices = 0 _MCP_GetConnectedDevices ( MCP_defaultVID , MCP_defaultPID , @ nbrDevices ) report ("MCP driver: Number of connected devices: " & nbrDevices ) END function ' ----------------------------------- ' If/when you gain access to a specific mcp2221 device, the device driver registers the fact ' and does not allow someone else to access that device. ' pwScripter is intelligent enough to release access to the DLL when pwScripter terminates ' or when it executes a newScript command. ' BUT pwScripter can not know that it should do more. UNLESS you tell it! ' This function is how you tell pwScripter what specially handling is required ' when pwScripter terminates or executes a newScript command. ' FUNCTION OnNewScript () TRY _MCP_CloseALL () END TRY inherit OnNewScript () ' calls any PRIOR onNewScript function i.e. they can be daisy-chained ' after execution THIS onNewScript will be unchained and deleted. END FUNCTION ' ----------------------------------- FUNCTION mcp_open_device_by_id ( optional deviceId = 0 ) ' returns a MCP device handle ' or ErrorFlag on error returnValue = _MCP_OpenByIndex ( MCP_defaultVID , MCP_defaultPID , deviceId ) IF ( returnValue == -1 ) then ' INVALID_HANDLE_VALUE= -1 according to the DLL user guide Report("mcp2221a DRIVER is accessible, but device index: " & deviceId & " not responding" ) Report("BE WARNED: if you DO NOT plug the USB-C firmly in to the mcp2221 the red led might light up" ) Report("but the device is not accessible. (At least on my hardware!)" ) returnValue = errorFlag END IF END function ' ----------------------------------- ' a simple way to see if a device's handle is valid ' Ask for its vid / pid FUNCTION mcp_checkDevice ( optional handle = MCP_handle ) ' Returns 0 if OKAY dim vid = 0 dim pid = 0 returnValue = _MCP_GetVidPid ( handle, @ vid , @ pid ) IF ( returnValue ) then report("MCP error code: " & ( returnValue) ) END if END function FUNCTION mcp_getDeviceInfo ( optional handle = MCP_handle ) dim wchar = wordArray (128) ' used to hold text (wide-char utf-16 16 bits/char) info returned by some DLL function calls report(chr(0x0a) & "MCP device info:-") wchar(0) = 0 _MCP_GetFactorySerialNumber( handle , wchar ) report = "Factory Serial Number: "& cstr ( wchar ) ' ----------------------------------- wchar(0) = 0 _MCP_GetSerialNumberDescriptor( handle , wchar ) report = "SerialNumberDescriptor: "& cstr ( wchar ) ' ----------------------------------- wchar(0) = 0 _MCP_GetManufacturerDescriptor( handle , wchar ) report = "GetManufacturerDescriptor: "& cstr ( wchar ) ' ----------------------------------- wchar(0) = 0 _MCP_GetProductDescriptor( handle , wchar ) report = "GetProductDescriptor: "& cstr ( wchar ) END Function ' ######################################################################################## ' GP ' ######################################################################################## FUNCTION mcp_GetGPIOsettings ( optional handle = MCP_handle ) dim pinFunction = bytearray ( 4 ) dim pinDirection = bytearray ( 4 ) dim pinValues = bytearray ( 4 ) dim i = 0 dim res = _MCP_GetGpioSettings( handle , 1, pinFunction , pinDirection , pinValues ) IF ( res ) then report ( "GetGpioSettings returned: "& hex(res) ) STOP END IF FOR i = 0 to 3 IF ( pinFunction(i) ) then continue for IF ( pinDirection(i) ) then report = "Pin " & i & ": input" ELSE report = "Pin " & i & ": output" END IF NEXT i END Function ' ---------------------------------------------------------------- ' functions specific to DIGITAL OUTPUT ' ---------------------------------------------------------------- FUNCTION mcp_writeGPIOBits ( optional handle = MCP_handle , optional pin0 = 0xff , optional pin1 = 0xff , optional pin2 = 0xff , optional pin3 = 0xff ) ' if a GP pin is not configured as a simple digital OUTPUT pin, then the provided value is ignored dim gpioValues = bytearray ( 4 , pin0, pin1, pin2 ,pin3) dim res = _MCP_SetGpioValues (handle , gpioValues) IF ( res ) then report("GetGPIOBits returned: " & hex(res) ) STOP END if END function ' ---------------------------------------------------------------- ' functions specific to DIGITAL INPUT ' ---------------------------------------------------------------- FUNCTION mcp_readGPIOBits ( optional handle = MCP_handle , optional pin = -1 ) dim gpioValues = bytearray ( 4 ) dim res = _MCP_getGpioValues (handle , gpioValues) IF ( res ) then report("getGPIOBits returned: " & hex(res) ) STOP ELSE res="" dim i FOR i = 0 to 3 SELECT case gpioValues(i) CASE 0 res = res & " 0" CASE 1 res = res & " 1" CASE else res = res & " _" END select IF ( pin == i ) then returnValue = gpioValues(i) EXIT function END if NEXT i report = res END if END function ' ---------------------------------------------------------------- ' functions specific to the ADC ' ---------------------------------------------------------------- FUNCTION mcp_writeADCVref ( optional handle = MCP_handle , dacVref ) dim ADCvalues = byteArray ( 4 ) returnValue = _MCP_SetAdcVref ( handle , 1, dacVref ) IF (returnValue ) then report ("writeADCVref error " & hex (returnValue ) & " Valid input values: 0,1,2,3 You provided: " & dacVref) STOP END IF END function FUNCTION mcp_readADCVref ( optional handle = MCP_handle ) dim ADCvalues = byteArray ( 4 ) returnValue = _MCP_GetAdcVref ( handle , 1, ADCvalues ) IF (returnValue ) then report ("GetAdcVref returned: " & hex (returnValue )) STOP ELSE dim txt = " ADC VRef: " SELECT case ADCValues(0) CASE 0 txt = txt & " Vdd" CASE 1 txt = txt & " 1.024 V" CASE 2 txt = txt & " 2.048 V" CASE 3 txt = txt & " 4.096 V" CASE else txt = txt & " invalid value - " & ADCValues(0) END select report ( txt ) END if END function FUNCTION mcp_readADCs ( optional handle = MCP_handle , optional targetADC = -1 ) dim adcValues = DWordarray ( 4,0,0,0,0 ) dim res = _MCP_GetAdcData ( handle, adcValues ) IF ( res ) then report (" GetAdcData returned: " & hex(res) ) STOP END if returnValue = -1 dim i dim txt = "ADC values: " FOR i = 0 to 2 txt = txt & " " & hex( adcValues(i) ) IF ( i == targetADC ) then returnValue = adcValues(i) EXIT function END if NEXT i IF ( returnValue == -1 ) then report ( txt) END function ' ---------------------------------------------------------------- ' functions specific to the DAC ' ---------------------------------------------------------------- FUNCTION mcp_readDACs ( optional handle = MCP_handle ) dim dacValues = bytearray ( 4 ) dim res = _MCP_GetdacData ( handle, dacValues ) IF ( res ) then report ( "GetdacData returned: "& hex(res) ) STOP END IF dim i dim txt = "DAC values: " FOR i = 0 to 2 txt = txt & " " & hex( dacValues(i) ) NEXT i report ( txt) END function FUNCTION mcp_writeDACVref ( optional handle = MCP_handle , dacVref ) dim Dacvalues = byteArray ( 4 ) returnValue = _MCP_SetDacVref ( handle , 1, dacVref ) IF (returnValue ) then report ("writeDacVref returned: " & hex (returnValue ) & " Valid input values: 0,1,2,3 You provided: " & dacVref) STOP END IF END function FUNCTION mcp_readDacVref ( optional handle = MCP_handle ) dim Dacvalues = byteArray ( 4 ) returnValue = _MCP_GetDacVref ( handle , 1, Dacvalues ) IF (returnValue ) then report ("GetDacVref returned: " & hex (returnValue )) STOP ELSE dim txt = " DAC VRef: " SELECT case Dacvalues(0) CASE 0 txt = txt & " Vdd" CASE 1 txt = txt & " 1.024 V" CASE 2 txt = txt & " 2.048 V" CASE 3 txt = txt & " 4.096 V" CASE else txt = txt & " invalid value - " & DacValues(0) END select report ( txt ) END if END function ' ---------------------------------------------------------------- ' generic things have been completed. ' ---------------------------------------------------------------- ' MCP_initialiseDLL () ' MCP_DisplayDLLinfo () ' mcp_Handle = mcp_open_device_by_id (0) ' mcp_getDeviceInfo ( mcp_Handle ) ' ---------------------------------------------------------------- ' define the GP pins for the demo ' ---------------------------------------------------------------- FUNCTION configureGPpinsDemo ( optional handle = mcp_Handle ) ' GP0: 0 GPIO GP1: 0 GPIO GP2: 0 GPIO GP3: 0 - GPIO ' 1 SSPND 1 - Clock Out 1 - USBCFG 1 - LED I2C ' 2 - LED UART RX 2 - ADC1 2 - ADC2 2 - ADC3 ' 3 - LED UART TX 3 - DAC1 3 - DAC2 ' 4 - Interrupt detection ' digital input, digital output, analogue input, analogue output dim pinFunction = bytearray ( 4 , 0 , 0 , 2 , 3 ) dim pinDirection = bytearray ( 4 , 1 , 0 , 0 , 0 ) dim pinValues = bytearray ( 4 , 0 , 0 , 0 , 0 ) _mcp_setGpioSettings( handle , 1, pinFunction , pinDirection , pinValues ) END function ' On my laptop (>8 years old) it manages abput 55 loops per second when pause=0 ' That suggests that a loop iteration, without pauses takes slightly less than 20 milli seconds ' Given that each iteration invokes 2 GP read and 2 GP write operations then ' a single GP operation takes about 5 milli seconds (that includes the USB driver processing ' and USB transport. And the pwS processing). ' For now, I am content! FUNCTION DEMO ( optional loopCount = 100 , optional pause = 100 ) ' DAC output value is 0..0x1f = 5 bits ' ADC resolution is 10 bits ' to scale ADC input to be a DAC output we must shift the ADC value 5 bits to the right report (chr(0x0a) & time & " Demo running" ) dim lc FOR lc = 0 to loopCount sleep(pause) _MCP_SetDacValue ( mcp_Handle , 1, ( mcp_readADCs ( ,1 ) rshift 5 ) ) mcp_writeGPIOBits ( , , mcp_readGPIOBits ( , 0) ) NEXT lc report (time & " Demo stopped" ) ' to show that the demo is finished lets flash the LED a few times FOR lc = 0 to 4 MCP_writeGPIOBits ( , 0,1,0,0 ) sleep(500) MCP_writeGPIOBits ( , 0,0,0,0 ) sleep(500) NEXT lc END function ' ---------------------------------------------------------------- ' start demo by getting the current GP settings and values ' ---------------------------------------------------------------- MCP_initialiseDLL () MCP_DisplayDLLinfo () ' just for info ' I am assuming that there is single connected MCP2221A breakout board ' The MCP2221A DLL enumerates the connected devices as 0..(n-1) ' where n is the number of connected devices. mcp_Handle = mcp_open_device_by_id (0) mcp_getDeviceInfo ( mcp_Handle ) ' just for info ' configure the selected MCP2221A's General Purpose pins configureGPpinsDemo (mcp_Handle) report () report("Device info:") MCP_getDeviceInfo (mcp_Handle) report("") report("Set initial values for the output GP pins for the demo.") MCP_writeGPIOBits ( mcp_Handle, 0,0,0,0 ) report("GP digital output = 0 GP analogue output = 0") _MCP_SetDacValue ( mcp_Handle , 1, 0x00 ) ' the ADC and DAC internal reference voltages are configurable. ' Set both to use Vdd which is 3.3 V unless a jumper is set underneath the mcp2221a board! report("") MCP_writeADCVref( mcp_Handle,0) MCP_writeDacVref( mcp_Handle,0) demo(1000,1) ' about 40 seconds on my Windows system.