AnyCloud Bluetooth Advertising Scanner (Part 2)

Summary

The second article in a series discussing the creation of a PSoC 6 + CYW43xxx Advertising Scanner using the AnyCloud SDK.  This article will use the learning from Part 1 to create a template project that starts the BLE stack.

Story

In the previous article I discussed the structure of the Cypress/Infineon Bluetooth Stack and its integration into AnyCloud.  A bunch of “theory”, well I say BS to that.  Let’s build something.

For this series of articles I will:

  1. Discuss an overview of Bluetooth Application Architecture (Part 1)
  2. Explain how to Start the AnyCloud Bluetooth Stack (Part 1) 
    1. Discuss the configuration structure: bt_platform_cfg_setting (Part 1)
    2. Discuss the configuration structure: wiced_bt_cfg_settings (Part 1)
    3. Discuss the Tasks created by the Bluetooth Stack (Part 1)
    4. Build the Basic Project (Part 2)
    5. Discuss BLE Advertising - Scanner/Observer (Part 3)
    6. Discuss BLE Advertising - Advertiser (Part 3)
    7. Add BLE Scanning Code to the project (Part 3)

    Recall from Part 1 that you need three things to startup the Bluetooth Stack

    • The Hardware Configuration Structure that matches : cybt_platform_config_t
    • The Bluetooth Stack Configuration Structure that matches : wiced_bt_cfg_settings_t
    • The Bluetooth Management Callback that matches : typedef wiced_result_t (wiced_bt_management_cback_t) (wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data);

    Then you need to call

    • The hardware initialization function : cybt_platform_config_init
    • The stack initialization function : wiced_bt_stack_init

    Ok let’s do this!

    Basic Project

    You can do all of these steps from the Eclipse IDE for ModusToolbox.  Or you can do it from the individual programs and the command line.  I like Visual Studio code, so this article will be done completely from the command line and individual configurators.

    Run the new project creator from the start menu.  Start by creating a project for the development kit that you have, in my case the one currently plugged into my computer is the CY8CKIT-062S2-43012, so that is what I pick.  But, this project will work with any of the WiFI/BT combo chips attached to PSoC 6.

    In previous articles I discussed the template that I use to get things going with FreeRTOS.  I won’t discuss that here, but I want FreeRTOS and the NTShell, so pick the IoT Expert FreeRTOS NTShell Template.

    After about a minute you should have a project.  I always like to build the project to make sure that everything is working before I get too far down the road of modifying anything.  Run “make -j build”

    Then to be sure it is working, program the development kit.

    When that is done, open up a terminal window and you should have a functioning base project.  Notice that I ran “help” and “tasks” from the command shell.

    Now that we have a basic project working, add the Bluetooth libraries.  Run the library manager by typing “make modlibs”.  Then select “bluetooth-freertos” and the library manager will automatically select the other libraries you need.  Press Update then Close.

    Next, run the bluetooth configurator by running “make config_bt”  This tool will help you make the bluetooth stack configuration structure.  When the configurator starts, press “New”

    Then select our device (the PSoC 6 and the Combo chip)

    Click on the “GAP Settings”.  Then press the Plus and add “Observer configuration”

    Then setup the scan settings (more detail on these numbers in the next article)

    • Low duty scan window (ms) = 60
    • Low duty scan interval (ms) = 60
    • Low duty scan timeout = deselected (meaning no timeout)

    Then save your configuration file.  Notice that I called it “btconfig”

    When you are done you will have a directory called “GeneratedSource” inside of your project with the needed files.

    The next step is to fix up the Makefile.  I like changing the name of the “App”.

    Then you need the “FREERTOS WICED_BLE” components.

    If you run make vscode it will update the workspace with all of the stuff needed for Visual Studio Code to be able to find all of the files.

    Inside of Visual Studio Code, create a new file called “bt_platform_cfg_settings.h” and add:

    Inside of Visual Studio Code, create a new file called “bt_platform_cfg_settings.c” and add:

    Inside of Visual Studio Code, create bluetoothManager.h.  Remember this is the Bluetooth Stack Management Callback

    Inside of Visual Studio code, create bluetoothManager.c.  This function does a whole lotta nothin… except saying that things got started.

    Next, update main.c with the required includes.

    Then update main.c to start the stack

    Now build and program it, remember “make -j build” and “make program”.  Look, we have a functioning stack with the two bluetooth thread running.

    In the next article Ill finally get around to building the Bluetooth Scanner.

    Keithley 2380-500-15 & 2380-120-60

    Summary

    In this article I discuss my ridiculous motivation for buying a new Keithley 2830-120-60 to replace my very functional Keithey 2380-500-15

    2380-500-15 & 2380-120-60

    While working on the IRDC3894 I spent a significant amount of time using the Keithley 2380 in Constant Current Mode.  The development kit that I was testing was configured to enable 1.2v output at 15A.  In the picture below I am pulling 1A.  You can see the Keithley set to pull 1A and it is actually drawing 0.9998A (plenty close)

    While I was testing the setup I would slowly increase the current.  In the picture below you can see that I got to 5.4A with no problem.

    But at 5.5A the trouble starts.  In the picture below you can see that I am asking for 5.5A but I am only getting 5.48A

    And the gap gets worse as I increase the current.

    So I posted on the Keithley site trying to figure out what was happening.  Was the Keithley dead?

    And unfortunately there is the answer.  The load has a minimum operating voltage of 4.5v when it is in the 15A mode.

    But the 2380-120-60 has a 1.8V operating voltage at 60A

    And when I get it plugged in I find that it will happily deliver 16A at 1.2V

    And it doesn’t start to roll over until 17A (at 1.2V)

    AnyCloud – Wireless Connection Manager (Part 2)

    Summary

    Part 2 of the discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently released for use with PSoC6 and 43xxx WiFi combos.

    The Story

    In the last article I walked you through creating a project using the wireless connection manager (WCM) which is one of the libraries that is part of the Infineon/Cypress AnyCloud SDK.  I introduced the wifi-mw-core, wifi-connection-manager and ntshell libraries.  In this article I will update the program to include commands to

    • connect (to an Access Point)
    • disconnect (from an Access Point)
    • print (mac address and ip address)

    Add the Connect

    I want to add a command that will let me issue a command line like

    • connect SSID (if it doesn’t have a passphrase)
    • connect SSID passphrase

    In order to connect to an Access Point you need to call the WCM API, cy_wcm_connect_ap.  Here is the function prototype:

    This function requires that you give it two arguments

    1. A pointer for a place to store the IP address (that comes from the DHCP server)
    2. A pointer to a structure of connection parameters.  That structure is as follows:

    Typically you would setup the “ap_credentials” part of the structure (unless you happen to know the MAC address of the AP you want to connect to).  Those credentials include the SSID and password as well as the security (WPA2 PSK etc…)

    Security is an enumeration of possible security types.

    Having to know the security of the AP is a total pain in the neck.  Where do you find the security from?  It turns out that when an AP beacons, the security of that SSID is one of the things that is broadcast.  What this means is that my program will need to

    1. When the connect command is called it should scan for the SSID that is part of the connect command & wait
    2. When the scan finds that SSID it will put the security type into the correct datastructure
    3. Then call the connect.

    The way that I will do this is to

    1. Build a filter (that looks only for the user specified SSID)
    2. Provides a pointer for a place to store the security type.

    I use the cy_wcm_scan function to do this.  Here is the function prototype:

    The scan filter is just a structure that specified

    1. A mode (which type of filter you want)
    2. The specific thing that you are looking for.

    The mode is simply an enumeration of the types of filters:

    What I want to do is start the scan and then wait for a semaphore.  To do this I will create a semaphore variable at the top of the netTask.c

    Inside of the switch I will

    1. Create a connection parameters structure (line 226-227)
    2. setup the scan filter (line 231-232)
    3. create the semaphore (line 235)
    4. run the scan (line 236)
    5. wait for the semaphore to be set or timeout (line 239) notice that I hardcoded it to 10 seconds

    In the scan callback I will check to see if I have real data (in other words the scan is not complete).  In the setup above I made the user data be a pointer to the place to store the security.  On line 54 I will store the security type that came back from the scan in the place pointed to by the user data pointer.  Then I will stop the scan and give the semaphore.

    Now back in the switch statement you can actually connect because you know the security type (line 244)  The else clause on line 253 handles the case where the timeout of the semaphore occurred, meaning that the scan didn’t find the AP.

    With all of the connection work done, you can add the scan command to “usrcmd.c”.  It just looks at the number of arguments (either 2 or 3), then sets up the message to send to the network task, the queues the message.

    Add the Disconnect Command

    The disconnect command is trivial.  Just call the disconnect api.

    Which you also need to add to the usercmd.c

    Add the Print Command

    The print command will have two optional parameters, IP (to print the current IP address) and MAC (to print our MAC address).  The first command is print ip.

    The MAC address command is also simple:

    And you need to add the print command to usrcmd.c

    All of this code is available on github at

    • git@github.com:iotexpert/wcm_example
    • https://github.com/iotexpert/wcm_example

    AnyCloud – Wireless Connection Manager (Part 1)

    Summary

    A discussion of using the Infineon (Cypress) PSoC 6 with a CYW4343W and the AnyCloud Connection Manager with Modus Toolbox.  The AnyCloud Connection Manager is an RTOS thread that lets you manage a connection to a WiFi network.  It knows how to scan for networks, attach, detach etc. and was recently released for use with PSoC6 and 43xxx WiFi combos.

    The Story

    In the WICED WiFI SDK there is an example program called “test.console” which allows you to use a UART command line to do networking “stuff”.  With the release of the new AnyCloud SDK I decided that I should rebuild some of that program using the PSoC and WiFi.  Basically a set of commands like “scan” to interact with the Radio World!  In the picture you below you can see that I use the command “scan” to list out the networks at my house.

    You can also use the command “help” to list out the commands.

    Architecture

    My implementation will have three tasks

    1. A Blinking LED Task (which doesn’t interact with any other tasks)
    2. The NT Shell – which will send commands to the network queue.
    3. The Network Task which will receive commands from the NT Shell task and trigger the Wireless Connection Manager to do something
    4. The Wireless Connection Manager which will interact with the WiFI Radio via the Wireless Host driver.

    Make the Basic Project

    To build this project start by creating a new project.  The development board that I had plugged into my computer when I began this project is a CY8CPROTO-062-4343W so this is the one I will select.

    In the new project creator pick the “CY8CPROTO-062-4343W”

    I created a FreeRTOS template project that does all of the right stuff.  I wrote an article about how to use the IoT Expert Manifestt here, and until you add the IoT Manifest to your setup you will not get the FreeRTOS Template project.

    After the new project work is done you should see

    Add the nt-shell, which comes from my IoT Expert library (read about how to add the IoT Expert library here).

    I have been on a kick of using Visual Studio code.  So, run “make vscode” to setup the project for Visual Studio Code.

    In the finder, copy the template files from nt-shell into your project.

    You can also do it with the command line.

    Edit main.c to include the configuration.

    Update the main.c to have the ntShellThread

    And start the ntshell task.

    When you want to add a command to the shell you need to do three things

    1. Add a function prototype for the command
    2. Add the command to the command list
    3. Write the function

    Here is an example of of the printargs command.  The shell will call your function with a ARGC=number of arguments and ARGV[] an array of the pointers to the actual arguments.

    Build and test your program.

    Turn on the Connection Manager and Core Middleware Library

    Now, add the wifi-mw-core library & Connection Manager using the library manager.  You can start it with “make modlibs”.  These two libraries are in the “WiFi Middleware” category.

    Copy the FreeRTOSConfig.h from the libs/wifi-mw-core/configs directory into your project (so you can modify it)

    Update the Makefile to include the WiFi components (line 71) and the MBED TLS configuration (line 86)

    Create networkTask.h/.c & Start the Task in main.c

    Now let’s create the networkTask.  This task will control all of the networking functions in the system.  The first file, networkTask.h, is the public interface.  It declares a Queue where you can push messages (line 5) an enumeration of the messages (lines 7-14), a definition of the message data (lines 17-22) and finally the network task declaration (line 24).

    Ill go ahead and modify main.c to start the yet to be written network task.  You need to include the header file for the task and define a handle for the task.

    Finally in main function, start the task.

    Create the file networkTask.c.  Make a bunch of includes.

    Now let’s define the actual task function.  This function will

    1. Call the wcm_init function to make a WiFi Station (lines 201-203)
    2. Tell the task that you would like to be called back when things happen (line 205)
    3. Initialize the Queue to receive command messages from other tasks.
    4. Make an infinite loop to receive the commands and process the messages.  Notice that I dont do anything with the message for now.  Ill add the code later.

    Create Utilities for Printing out the IP and MAC Address

    It the network task I want to be able to print out IP address (both IPV4 and IPV6).  I also want to be able to print out 6-byte MAC address.  In the Cypress drivers, an IP address is a structure that holds either a IPV4 or and IPV6 address.  It then contains the 4 or 6 bytes of the address.  Here is the type definition.

    The IP v ersion is just an enumeration.

    To print an address, figure out which version you are working on.  Then dump the raw bytes.  Notice in the IPV4 case it is encoded into a uint32_t as 4 continuous bytes.

    A MAC address is just an array of uint8_t of length CY_WCM_MAC_ADDR_LEN  (which we pound defined to 6)

    So, the print is just a loop. (probably should have done something slightly better so I dont end up with the trailing : – oh well)

    Add the Scan Command

    For the scan I want to print out the:

    1. SSID
    2. RSSI (in dBM)
    3. Channel
    4. Band
    5. Speed
    6. Type of Ap
    7. Country Code
    8. MAC address of the Access Point (AKA BSSID)
    9. Type of Security

    In order to have the WCM run a scan you need to call the function cy_wcm_start_scan.  What this will do is tell the 4343W to scan all the channels on the 2.4GHZ band and listen for access point beacons.  This function has three arguments

    1. A function pointer to call back when you find an AP
    2. A user settable data pointer
    3. A filter (which can limit to an SSID, BSSID or RSSI)

    Here is my version of the scanCallback which I put in the networkTask.c file.

    The result_ptr is a pointer to a structure that contains the data for the found access point.

    The other parameter to the callback is the status.  The status will either be CY_WCM_SCAN_COMPLETE or CY_WCM_SCAN_INCOMPLETE.  The first thing that to do is see if this callback is the one that tells me that the scan is complete, if so I just return (and don’t print anything)

    Then I print out the raw SSID, Signal Strength and Channel.

    Next I figure out what channel we are talking about.  The 4343W is single band 2.4GHZ, however, other Cypress chips have dual band.

    Then I printout the maximum data rate, which is 0 for all of my test cases.  I have no idea why.

    Then I printout what type of AP we are talking about.

    Then the country code.

    Then the Basic Service Set ID of the AP, which is also known as the MAC address of the AP.

    Then the security type.

    With a complete scanCallback function I can now update the networkTask to deal with the queued commands of net_scan type.  This simply either stops or starts the scan based on the message parameter.

    The last things to do is to add the scan command to the usrcmd.c

    OK.  Let it rip.  You should be able to run network scans.  In the next Article I will add a connect and disconnect commands.

    You can find all of this example code at https://github.com/iotexpert/wcm_example

    Infineon SupIRbuck – Low Voltage/High Current Measurement

    Summary

    This article will show you the steps to produce 12A from and IRDC3894.  It also discusses low voltage high current measurement and burden voltage.

    The Story

    In the last few weeks I have been working on a TypeC to Infineon SupIRbuck power supply that will turn 20V@3A into 5V@12A.

    In that process I have been working with a Keithley 2380-500-15 which can act as a load simulator for my design.  The 15 in name means that it can pull 15A which should be more an adequate to test my design.  Unfortunately when I was looking at the specs, I read the part about “15A” but not the part about the “Min Operating Voltage in the 15A range = 4.5V”

    And what I really should have bought (and now have) is a 2380-120-60

    Big Resistors

    But I really wanted to be able to measure the current coming out of the IR3894.  So, I decided to buy some “Big” resistors.  Well they are not actually high resistance, but they are HIGH power. 35W and 50W.  Unfortunately they are also $4 each.  Here is a 0.33Ω 50W resistor.  (I will totally understand the value of that giant heat sink later on in this article)

    My measurement setup looks like this:

    And actually looks like this terrible mess:

    Start the measurements

    I bought 7 different resistors ranging from 0.1Ω to 1Ω.  This means that I should be able to get something like this table.  Note that the 0.1Ω is marked in red because it exceeds the current limit of my multimeter. (i.e. don’t do that)

    V R A W Rating
    1.2 0.10 12.0 14.4 35
    1.2 0.15 8.0 9.6 50
    1.2 0.20 6.0 7.2 35
    1.2 0.33 3.6 4.4 50
    1.2 0.50 2.4 2.9 35
    1.2 0.75 1.6 1.9 50
    1.2 1.00 1.2 1.4 50

    I wasn’t exactly sure what was going to happen so I decided to start with the 0.33Ω resistor

    I was hoping to get 1.2V/0.33Ω = 3.6A yet I end up with 1.99A where is my other 1.6A?

    I put in a 0.1Ω, 0.15Ω and 0.75Ω and measured the current.  Then I calculate the effective resistance of the system and it turns out that there is essentially another 0.27Ω in series with my R1

    V=I(R1+Rb)

    V/I-R1 = Rb

    V A R1Ω RbΩ R1+RbΩ
    1.2 2.0 0.33 0.27 0.60
    1.2 3.16 0.10 0.28 0.38
    1.2 2.85 0.15 0.27 0.42
    1.2 1.175 0.75 0.27 1.02

    Where in the world is the other 0.27Ω?

    Melt the Probe

    This leads me to the great idea that is just the lead wires, and that I ought to just pull out the resistor and see what happens.  Well, what happens is that I melt the probe, and I still don’t get numbers that make sense.

    Burden Voltage

    The real story is, of course, that digital multimeters are hardly “ideal” and that when you are measuring current what you are really doing is measuring the voltage across a “shunt resistor”.  A shunt resistor is just a small valued highly precise resistor.  The voltage across this resistor is also known as the burden voltage (which is why I called it Rb above).  Here is a picture out of the Keysight documentation.

    But how big is that resistor?  Well, unfortunately it is not specified directly in the documentation.  But, when you look at the data sheet you find that the maximum burden voltage is 0.5V at 10A.

    This means that shunt resistor is no more than 0.5v/10A=0.05Ω.  I just ordered a new Keithley DAQ6510 Digital Acquisition System Multimeter (which Im very excited about) that has the following table in documentation where it says the shunt resistor is 100mΩ for the 3A range.

    Measure the Lead Resistance

    So now we know that the shunt resistor is something like 0.05Ω.  That means the rest of the resistance has to be in the test setup.  So

    V=(R1 + Rl + Rb)*I … the lead resistance + the shunt resistor + the actual resistor.  I go ahead and calculate what the lead resistance with several different resistors.

    This means the resistance of my lead wires must be something like 0.23Ω

    V A R1 Rl Rb R1+Rb+Rl VR1 VRl VRb
    1.2 2.00 0.33 0.23 0.04 0.37 0.66 0.46 0.08
    1.2 3.16 0.10 0.23 0.04 0.15 0.32 0.73 0.16
    1.2 2.85 0.15 0.23 0.04 0.19 0.43 0.66 0.12
    1.2 1.18 0.75 0.23 0.04 0.79 0.88 0.27 0.05

    Again I start to look for the lead wire resistance … 0.6Ω for the melted lead.  Curious.

    It is pretty easy to get some crazy measurements.  2.7Ω just pushing two banana plugs together (though you can see it blinking)

    If I measure the red banana plug wire looped back the measurement is 0.016Ω – OK that is pretty small

    And the black one is almost the same.

    After some experimenting mixing and matching cables together the lowest I manage to get in a configuration that I can actually plug together is 0.15Ω which gave me 7.8A.

    So where does this leave me?  To tell you the truth it leaves me a bit frustrated.  I really wanted to get 12A out of my setup (which is what it should be able to do).  But the most I can safely measure is 10A.  And the lowest combination of resistors I seem to be able to get is 0.15Ω.  So I decide to solder the 0.1Ω resistor straight into the board and see what happens. (yes that is some ugly soldering)

    And now Im really frustrated because when I turn on the bench power supply I get 9.9V and 0.6A … even though it is set for 12V

    And when I look at the output voltage I get 0.4V.  Which means it isn’t working.  Why?  I don’t know…. which is beyond annoying.  Walk away now I say to myself (actually that was my wife yelling at me 🙂 )

    24 Hours Later

    After sleeping on it, I remember that the Enable pin is used as an “Under Voltage Lock Out”.  The purpose of the UVLO is to not turn on until the input voltage has enough power to supply the system.  Given that I am am asking for 12A I realize… maybe I need to “enable” later in the power supply voltage rise.

    So what I do I solder in a jumper to “Enable” then I press fit it into the ground.  Then turn on the power supply.  I measure the output as 0V.  That is good.  Then pull the enable jumper wire and let the IR3894 turn on.

    Sure enough.  When I look at the input it gets to 12V@1.4A and the output is still steady at 1.2v.  And my 0.1Ω is very hot.  I suppose that heatsink tab is there for a  reason.

    I know from Ohms law that I am getting 12A@1.2V.  So the IR3894 seems to do the trick!

    Cypress Type-C Barrel Connector Replacement + Infineon Buck DC/DC (Part 3)

    Summary

    This article walks you through the steps to test the CY4533 Type-C BCR & IR3894 under the load conditions from 1A to 12A.  In the previous article, I supplied power to the IR3894 using a bench top power supply.  For this set of experiments I will use a Type-C wall wart connected to the Cypress 4533 BCR development kit to supply power.

    Test the BCR

    The first thing that I do is connect the whole mess together like this:

    Here is how it looks on my desk.  Note that the Keithey can measure current and voltage… but that I don’t have a way in this setup to measure either the voltage/current from the power supply or the current out of the CY4533

    I step the output load from 1A to 12A in 1A increments.  I am super happy to see that the output voltage of the IR3894 is perfectly regulated to 1.198V.  It is also interesting to see that the Type-C power supply is able to keep the voltage within 3.25% of nominal even when I am using 12A on the IRDC3894 output (probably around 1.5A from the Type-C)

    Measure the Input Current

    In the previous article I used the current measurement from the Keithley bench top power supply.  In the setup above I don’t have a way to measure the actual input current.  To fix this put my new Keithley DAQ6510 in series with the IRDC3894 board.  Like this:

    Then I step through the 1A-12A load conditions.  Once again the IR3894 provide a very well regulated voltage and current (exactly the same as before so I didn’t write them down)

    Here is a table with the data from the previous post (without the Type-C power supply) versus the Type-C power supply.

    2230-30-1 Power Supply With 6510 current meter in input path
    Vin Iin Win Vout Iout Wout Eff Vin Iin Win Eff-C Loss
    12 0.27 3.24 1.198 0 0 0%
    12 0.129 1.548 1.198 0.998 1.195604 77% 11.91 0.129 1.53639 77.8% -0.6%
    12 0.239 2.868 1.198 1.998 2.393604 83% 11.8 0.242 2.8556 83.8% -0.4%
    12 0.345 4.14 1.198 2.998 3.591604 87% 11.7 0.352 4.1184 87.2% -0.5%
    12 0.454 5.448 1.198 3.998 4.789604 88% 11.59 0.467 5.41253 88.5% -0.6%
    12 0.564 6.768 1.198 4.999 5.988802 88% 11.47 0.586 6.72142 89.1% -0.6%
    12 0.677 8.124 1.198 5.998 7.185604 88% 11.36 0.709 8.05424 89.2% -0.8%
    12 0.792 9.504 1.198 6.998 8.383604 88% 11.25 0.837 9.41625 89.0% -0.8%
    12 0.909 10.908 1.198 7.998 9.581604 88% 11.13 0.97 10.7961 88.8% -0.9%
    12 1.029 12.348 1.198 8.998 10.779604 87% 10.95 1.115 12.20925 88.3% -1.0%
    12 1.152 13.824 1.198 9.999 11.978802 87% 10.85 1.258 13.6493 87.8% -1.1%
    12 1.277 15.324 1.198 10.998 13.175604 86% 10.8 1.401 15.1308 87.1% -1.1%
    12 1.406 16.872 1.198 11.997 14.372406 85% 10.68 1.558 16.63944 86.4% -1.2%

    These measurements use 1A/3A range on the Keithley DAQ6510 DMM, which means that they have a 100mΩ shunt resistor in series which drops the voltage by V=IR or about 0.1-ish volts.  This explains most of the difference from the Power Supply to the Type-C setup.

    It is actually very interesting to look at the data to see the impact of lowering the input voltage on the efficiency of the IR3894.  It appears that at the highest load and lowest input voltage the efficiency is down by 1.2%

    Watch the Sunrise

    While I was sitting there at my desk thinking about what to do next, I decided that the best thing to do was go sit in my hottub and watch the sunrise on God’s country.

    USB C Power Meter Tester

    I was hoping to be able to measure the input current and voltage from the Type-C power supply so that I could calculate the efficiency of the CY4533 EZ BCR.  And as a result the efficiency of the whole system.  There wasn’t a place on the Type-C development kit to make these measurements, but the Cypress Apps manager for Type-C – Palani – said I should buy something like this from Amazon.

     

    So I did.  You can plug it into Type-A or Type-C and it will tell you how much V/I are coming out.  In the picture below you can see 20.4v@0.11A

    Even better it has a handy-dandy mode where it can display Chinese?

    Here is a picture in my actual setup:

    And a picture of the whole crazy setup.

    Now I step through my 12 load conditions from 1A to 12A and record the V/I from the Fluke and the USB Power Tester.

    Here is the data in table form with power and efficiency added.

    Type C Power Tester
    Vin Iin Win Eff-No Meter
    11.99 0.15 1.7985 66.5%
    11.95 0.26 3.107 77.0%
    11.92 0.36 4.2912 83.7%
    11.88 0.48 5.7024 84.0%
    11.85 0.59 6.9915 85.7%
    11.82 0.7 8.274 86.8%
    11.79 0.82 9.6678 86.7%
    11.75 0.94 11.045 86.8%
    11.71 1.07 12.5297 86.0%
    11.68 1.2 14.016 85.5%
    11.64 1.33 15.4812 85.1%
    11.6 1.46 16.936 84.9%

    Next, I plot the new data with the previous two plots.  Obviously, it is screwed up.  I would bet money that the data points at 2A, 4A and 12A are wrong.  But, I don’t think that it is worthwhile to take steps to figure out the real current.  So, I suppose that is what you get from a $19 power meter.

    Efficiency of CY4533 EZ-PD BCR

    I had really wanted to measure the efficiency of the BCR setup.  To do that I needed to be able to measure the output power (V/I) and the input power (V/I).  Unfortunately the power meter doesn’t seem to be very good… so I suppose that I will have to wait to build my real board where I can install some power jumpers the real numbers.

    Cypress Type-C Barrel Connector Replacement + Infineon Buck DC/DC (Part 2)

    Summary

    In this article I will show you how to use a Keithley 2380 (actually two different ones) to test the output of the IRDC3894 12V->1.2V 12A buck development kit.

    The Story

    To this point I have written several articles about my process of designing a power supply for my new IoT device.  It needs to provide for quite a bit of power, actually 60W is what I am planning on.  I really wanted to make sure that the IR3894 chip would do what it says it would, specifically supply 12A.  The development kit is pretty simple.  There are two banana plug to  provide power to Vin and two banana plus for the load.

    For this round of tests I will Keithley 2230-30-1 to provide power and I will use my Keithley 2380-120-60 to serve as the load.

    The two mini grabbers are attached to to remote sensing terminals on the Keithley 2380.

    After I had it all hooked up I went in 1A increments from 0 to 12A, then I went in 0.1A increments until I ran out of input power.

    Here is the actual data table.  Note that I added columns to show the calculated input power.  And I calculated the efficiency of the system Wout/Win

    Vin Iin Win Vout Iout W Eff
    12 0.27 3.24 1.198 0 0 0%
    12 0.129 1.548 1.198 0.998 1.195604 77%
    12 0.239 2.868 1.198 1.998 2.393604 83%
    12 0.345 4.14 1.198 2.998 3.591604 87%
    12 0.454 5.448 1.198 3.998 4.789604 88%
    12 0.564 6.768 1.198 4.999 5.988802 88%
    12 0.677 8.124 1.198 5.998 7.185604 88%
    12 0.792 9.504 1.198 6.998 8.383604 88%
    12 0.909 10.908 1.198 7.998 9.581604 88%
    12 1.029 12.348 1.198 8.998 10.779604 87%
    12 1.152 13.824 1.198 9.999 11.978802 87%
    12 1.277 15.324 1.198 10.998 13.175604 86%
    12 1.406 16.872 1.198 11.997 14.372406 85%
    12 1.42 17.04 1.198 12.098 14.493404 85%
    12 1.434 17.208 1.198 12.198 14.613204 85%
    12 1.448 17.376 1.198 12.297 14.731806 85%
    12 1.462 17.544 1.198 12.398 14.852804 85%
    12 1.477 17.724 1.198 12.498 14.972604 84%
    12 1.49 17.88 1.198 12.59 15.08282 84%

    When I plot the data there is something sticking out like a sore thumb.  WTF?  At first I assume that I typed in the wrong number when I transposed the hand written data to the spreadsheet.  So I went and looked at the data table where it appears that I typed it in correctly.  Does the efficiency really have a peak like that?

    I decided to go remeasure the 5A datapoint.

    Then I looked at my handwritten data sheet where I find that I transposed the last two digits of the input current. (I definitely should automate this measurement)

    OK… now the plot looks way better

    When I compare the plot from the data sheet versus my data on the same scale (about) they look very similar.  All seems good.

     

    Cypress Type-C Barrel Connector Replacement + Infineon Buck DC/DC (part 1)

    Summary

    In this article I will walk you through the first steps of building a complete Type-C power supply that will look like this:

    The Project

    I have been working on a project that will drive several strings of WS2812 LEDs.  Specifically, a CapSense dimmable “IoT-ified” nightlight using a PSoC 6 attached to a CYW43012 attached to a string of WS2812 LEDs.   Right now, I have this thing built up with a development kit + a breadboard + 2 wall warts and it is sitting on the floor beside my bed.

    When you see this picture, I’m sure that you are thinking.  “You are probably going to be sleeping on the floor beside your bed if you don’t do something better than that.”  And you would be right.  I know that I want a single PCB in a nice 3-d printed box that does all of this.  I also know that I want to use Type-C instead of a normal 12v wall wart.  When I started this I had only the vaguest ideas about how to turn Type-C into something that could drive a bunch of LEDs and a PSoC.  How much power do I need?  And at what voltages?  That seemed like the first question that needed answering.

    First, I put a meter on a string of 144 WS2812 LEDs.  Wow, 5V at ~4A when the LEDs are full on.  That is 20W per string… basically 30mA per WS2812.

    To make a board that can drive three strings of these LEDs I am going to require 3x20w + whatever the PSoC takes.  A bunch.  But where should I get this much power?  The answer is I am going to start with a laptop Type-C charger like this one from Apple (which I have several of)

    The first/next question is, how do I tell the Apple adaptor what voltage/current I want?  It turns out that Cypress is the leader in Type-C chips and we make the perfect chip for this application.  It is called the CYPD3177-24LQXQ and is known colloquially as the EZ-PD™ Barrel Connector Replacement (BCR).  This is good because that is exactly what I want to do, replace a wall wart barrel with a Type-C.

    Cypress CY4533 Development Kit

    To get this going I start with the Cypress CY4533 development kit which you can see in the picture below.

    This board has

    1. A place to plug in Type-C
    2. A 5 position switch to tell the EZ-PD chip to select (5, 9,12,15 or 20V)
    3. Screw terminals for the output voltage
    4. A header with an I2C connection to the EZ-PD chip
    5. A load switch to isolate the load

    Here is a block diagram

    The kit quick start guide has a picture of exactly what I did next

    When I turned the selector, I noticed that the output from my Apple charger was (5, 9, 9, 9, 20) and wondered why.  Yet, when I measured another Type-C power supply I got (5, 9, 12, 15, and 20).  It turns out that when you read the fine print on the side of the charger it tells you the answer.  Here is a picture of the side where unfortunately you can’t read (but I used a magnifying glass)

    • 20V @ 3A = 60W
    • 9V @ 3A = 27W
    • 5V @ 2.4A = 12W

    The kit guide gives you the answer as to why 5,9,9,9,20:

    Infineon

    OK.  All that is great, but how do I power my board where I need 5V@12A + 3.6V + 3.3V + 1.8V, this is where Infineon comes into the picture.  Actually, to be completely clear, Infineon came into the picture starting mid-last year when they offered to pay $10B-ish for Cypress.

    Infineon makes a line of Buck regulators which are perfect for solving the first part of my problem because

    1. They take high-ish voltage inputs (up to 21V)
    2. They can supply high-ish currents at the right voltage (up to 35A)

    These regulators are called the “SupIRBuck” and are part of the “Integrated POL Analog Voltage Regulators (Industrial)

    So, I ordered a development kit… unfortunately I  choose the wrong one, IRDC3823 which is 12V @ 3A.  However, it was close enough for me to try out.

    The board came in a box with the kit and a USB stick.

    The USB Stick had the Kit Guide, Datasheet, and Gerber Files. That was nice of them.

    The kit it actually very simple.  It has a place to plug in your input supply (the two terminals on the left).  And it has a place to plug in the output.

    The board also has a place to configure the startup time of the Buck (the little four position jumper).  When I connected the EZ-PD BCR kit to the IR3823 Eval Board, look what I got.  1.2V.  Great.

    This is cool and all of that… but I have a bunch of questions that need answering

    1. How do I get 5V out (instead of 1.2V)
    2. Why does the the kit guide say a maximum of 13V on the input?
    3. How do I configure the PGOOD signal to be compatible with the PSoC
    4. How do I measure the efficiency?
    5. What is all this stuff about switching frequency and what is the right number?
    6. What should I choose for SS_Select and why?
    7. What is an “external VCC about?
    8. How do I get 5A (instead of 900mA)?
    9. How do I talk to the EZ-PD chip via I2C?

    All of these questions and more are deferred to future articles.

     

     

     

     

    MBED OS & CY8CKIT_062S2_43012 & Segger emWin & NTP

    Summary

    Have you ever wondered about the nature of time?  Given the demographics of my readers I am quite sure that all of you have pondered this topic.  In this article I will solve one of the great mysteries of human kind.  What time is it?  Well that may be a little bit over dramatic 🙂  Actually what I will show you is how to use the CY8CKIT-062S2-43012 development kit to get time from the internet using the Network Time Protocol (NTP), update the PSoC 6 RTC and display it on the CY8CKIT-028-TFT using MBED OS.

    Unfortunately I will not show you a beautiful way to convert UTC to Eastern Time because I don’t actually know what that way would be which is very frustrating.  Every way that I know requires me to drag a lot of crap into my PSoC6 which I don’t really want to do.

    For this article I will discuss:

    1. MBED OS Project Setup
    2. MBED OS Event Queues
    3. The RTOS Architecture
    4. The Display Function(s)
    5. The NTP Thread
    6. The WiFI/Main Thread
    7. The Whole Program

    Project Setup: Create and Configure Project + Add the Libraries

    You should start this project by creating a project by running “mbed new NTPDemo” or by using mbed studio to create a new project.  To run this project requires at least mbed-os-5.13.3.  You have two basic choices to get the latest mbed.  For some reason which I don’t totally understand when you run mbed new it gives you a slightly older version of mbed-os.  To get a new version you can either “cd mbed-os ; mbed update mbed-os-5.13.3” or to get the latest “cd mbed-os ; mbed update master”.

    In this project I use three libraries, emWin, the IoT Expert ST7789V library (for the display) and the ntp-client library.  To add them run

    The emWin library requires that you tell emWin about which version of the library .a to link with.  You can do this by adding this to the mbed_app.json

    MBED OS Event Queues

    For this project I will use one of the cool RTOS mechanisms that is built into MBED OS,  the “EventQueue“.   There is a nice tutorial in the MBED OS documentation.  An EventQueue is a tool for running a function “later” and in a different thread context.  What does that mean?  It means that there is a thread that sits around waiting until you tell it to run a function.  You tell it to run the function by pushing a function pointer into it’s EventQueue.  In other words, an EventQueue is a thread that waits for functions to be pushed into queue.  When the function is pushed into the queue it runs it.

    How is this helpful?  There are a several of reasons.

    • If you are in an ISR it allows you to defer execution of something to the main program.
    • It can be used to serialize access to some resource – in my case the display.
    • It allows you to schedule some event to happen regularly

    When MBED OS starts it automatically creates two of these event queues one of the queue threads runs at “osPriorityNormal” and can be accessed via mbed_event_queue();  The other event queue runs at “osPriorityHigh” and can be accesed by mbed_highprio_event_queue();  For some reason (which I don’t understand) these queues are documented on a separate page.

    The RTOS Architecture

    Here is a picture of the architecture of my program.

     

    The Main Thread

    The main function which is also the main thread, which then becomes the WiFi Thread

    1. Initializes the GUI
    2. Starts up the Display Event Queue
    3. Turns on the WiFi and attaches a callback (to notify the program of WiFI Status Changes)
    4. Try’s to connect to the WiFi Network
    5. If it fails, it updates the display and try’s again after 2 seconds
    6. Once it is connected it starts up the NTP Server Thread
    7. And then waits for the WiFi semaphore to be set… which only happens if WiFi gets disconnected at which point it goes back to the start of the WiFI connection and try again.

    Display Event Queue

    Display EventQueue is used to run functions which update the display.  By using an EventQueue it ensure that the Display updates happen serially and there are no display resource conflicts.  The four functions are

    1. updateDisplayWiFiStatus
    2. updateDisplayWifiConnectAttempts
    3. updateDisplayNTPCount
    4. updateDisplayTime

    I wanted a function which could display the state of the WiFi connection on the screen.  This is a string of text which is generated in the connection status function.  In order to send the message, the connection status function will “malloc” which then requires the updateDisplayWiFiStatus function to free the memory associated with the message.

    When I started working on this program I had a bug in my connections so I added the ability to tell how many WiFI connections attempts had happened.  I also wondered how many times there might be a disconnect if I ran this program a long time.  The answer is I ran it for two days and it didn’t disconnect a single time.  This function simply takes a number from the caller and displays it on the screen.  Notice that I use snprintf to make sure that I don’t overrun the buffer (which I doubt could happen because I made it 128 bytes).

    I was curious how many times the NTP connection would happen.  So I added the ability to display a count.  Notice that I use a static variable to keep track of the number of times this function is called rather than pushing the number as an argument.  Perhaps this is a design flaw?

    The main display function is the seconds which is displayed in the middle of the screen.  I get the time from the RTC in the PSoC and is set by the NTP Server.  Notice my rather serious hack to handle the Eastern time difference to UTC… which unfortunately only works in the Summer.

    NTP Time Thread

    The Network Time Protocol was invented in 1981 by Dr. David Mills for use in getting Internet connected computers to have the right time.  Since then it has been expanded a bunch of times to include Cellular, GPS and other networks.  The scheme includes methods for dealing with propogation delay etc.  However, for our purposes we will just ask one of the NIST computers, what time is it?

    The way it works is that you setup a structure with 48 bytes in it.  Then you open a UDP connection to an NTP server (which NIST runs for you) then it will fill out the same structure with some time data and send it back to you.  Here is the packet:

    The code to send the packet is really simple.  The only trick is that when you send data on the network you almost always use big endian, so you need to use the function nthol to convert.

    The times in the structure are represented with two 32-bit numbers

    • # of seconds since 1/1/1900 (notice this is not 1970)
    • # of fractional seconds in 1/2^32 chunks (that ain’t a whole lotta time)

    The four numbers are

    • Reference Time – when you last sent a packet
    • Origin Time – when you sent the packet (from your clock)
    • Receive Time – when the NTP server received your packet
    • Transmit Time – when your NTP server sent the packet back to you

    You know when you send the packet – called T1.  You know when you received the packet – called T4.  You know when the other side received your packet – called T2 and you know when the other side sent the packet called T3.  With this information you can calculate the network delay, stability of the clocks etc.  However, the simplest thing to do is to take the transit time, which is in UTC, and set your clock assuming 0 delay.

    In MBEDOS to set the RTC clock in the PSoC you call the function with the number of seconds since 1/1/1970.  Don’t forget that the time that comes back from NTP is in seconds since 1/1/1900.

    Given that the PSoC 6 RTC counts in seconds you can just ignore the partial seconds.

    WiFi Semaphore

    At the top of main I registered to WiFi that I want a callback when the state of the WiFi changes.

    This function does two things.

    • Updates the screen as the state goes from unconnected to connected
    • Unlocks a semaphore to tell the main thread to reconnect.

    The Whole Program

    Here is the whole program.

     

    MBEDOS Libraries & emWin Configuration Files

    Summary

    I have written a fair amount about Graphics Displays, using the Segger emWin graphics library and MBED OS.  I have found it irritating to do all of the configuration stuff required to get these kinds of projects going.  I inevitably go back, look at my old articles, find the github repository of my example projects etc.  This week I wanted to write some programs for the new CY8CKIT-062S2-43012 development kit so I thought that I would try all of the Cypress displays using that development kit.  Rather than starting with example projects, this time I decided to build configurable mbedos libraries. In this article I will show you how to build configurable mbed os libraries which will allow you to use the emWin Graphics Library with all of the Cypress display shields.

    In this article I will walk you through:

    • The CY8CKIT-032 & SSD1306 Display Driver & emWin
    • MBED OS Libraries
    • MBED OS Configuration
    • Configuration Overrides
    • The SSD1306 emWin Configuration
    • Using the SSD1306 Configuration Library
    • emWin Configuration Libraries

    The CY8CKIT-032 & SSD1306 Display Driver & emWin

    The CY8CKIT-032 has a little 0.96″ OLED display that is attached to the Salomon Systech SSD1306 Display Driver.  I have written quite a bit about this little screen as it is cheap and fairly easy to use.  It became even easier when we released the Segger emWin SPAGE display driver.  And with my new library it should be trivial to use and configure for your setup.

    You can read in detail about the functionality here but in short:

    • The display driver chip is attached to the PSoC via I2C
    • You need to provide the Segger emWin driver
      • GUIConfig.h/cpp – Segger GUI configuration
      • LCDConf.h/cpp – Setup files for the LCD
      • GUI_X_Mbed.cpp – RTOS control functions for delays etc.
      • ssd1306.h/c – physical interface to the SSD1306 controller
    • You need to initialize the PSoC I2C before talking to the display
    • You need to initialize the display driver chip before drawing on the screen

    In general all of this configuration will be the same from project to project to project.  However, you may very will find that you have the display connected to a different set of pins.  I suppose that would put all of these files into some directory.  Then you could copy that directory into your project every time.  Which would leave you with modifying the configuration to meet your specific board connection.  The problem with that is you have now deeply intertwined your project with those files.

    MBED OS has given us a really cool alternative.  Specifically the Library and configuration systems.

    MBED OS Libraries

    An MBED OS library is simply a git repository.  Just a directory of source files.  When you run the command “mbed add repository” it does two basic things

    1. It does a “git clone” to make a copy of the repository inside of your project.
    2. It creates a file with the repository name.lib which contains the URL to the version of the repository

    Here is a an MBED add of my graphics configuration library for the SSD1306

    Notice that when I “ls’d” the directory that all of file required to confiugure emWin for the SSD1306 became part of my project.  And the file mbed-os-emwin-ssd1306.lib was created with the URL of the github repository.

    When you run “mbed compile” the build system just searches that directory for cpp and h files turns them into .0’s and add them to the the BUILD directory.  However, before it compiles it run the configuration system.

    MBED OS Configuration System

    The configuration system takes the file “mbed_lib.json” parses it and turns it into a C-header file called mbed_config.h.  The format of this file is

    • The name of the component – in this case “SSD1306_OLED”
    • The parameters of the component SDA, SCL, I2CADDRESS and I2CFREQ

    This header file is then placed into the BUILD directory of your project and is included as part of #include “mbed.h”

    If you open mbed_config.h you will find that it creates #defines of the component parameters

    This is really nice because I can then reference those #defines in my source code.

    Configuration Overrides

    When you are building the library you can create an arbitrary number of these parameters which are then applied to all of the uses of that library.  Or if there is some reason why one target is different you can specify the parameters for that specific target by changing the mbed_lib.json.  For instance if the CY8CKIT_062S2_43012 need a 100K I2C frequency instead of 400K (it doesn’t), you could do this:

    The application developer is also allowed to over-ride the parameter by providing the target overrides in the MBED OS file “mbed_app.json”.  Notice that the way you specify the parameter name is different in this file than the mbed_lib.json.  In this case you give it the name of the library.parametername.  Here is an example setting the I2CFrequency to 100K

    Which would result in a change to the generated #define in mbed_config.h

    Notice that you can specify a “*” to match all of the targets, or you can specify the exact target.

    The SSD1306 emWin Configuration

    I use the configuration system to generate #defines for the

    • SCL/SDA Pin Numbers
    • I2C Address
    • I2C Frequency

    Which lets my use those #defines in ssd1306.cpp

    And

    Using the SSD1306 Configuration Library

    Lets make an example project that uses the CY8CKIT_062S2_43012 and the CY8CKIT032 using the Segger graphics library and my configuration library.

    Start by make a new project, adding the emWin library and the configuration library.  It should look something like this

    Now edit the mbed_app.json to add the emWin library

    Create the main.cpp which simply initializes the display and displays “hello world”