Simple Serial Cleanup V00J

Because of the size and complexity of simple_serial.c, I decided I would work on cleaning it up for this week’s post.

To start with, I created two new files for postable events called events.c and events.h.  I moved the function task_handler() from simple_serial.c to events.c and added a //TODO comment to remind me to clean up the task handler code.  This created a bunch of errors because I haven’t included any of the library header files.  So I stepped through the process of adding the necessary header files.  I copied all of the include statements from simple serial.c to events.c and eclipse reported no errors.  Next, I commented out one line at a time of the include statements. When eclipse indicated errors in the file, I uncommented that line and moved on to the next.  I ended up only needing two include statements: uart.h and user_interface.h.   I moved the prototype of task_handler from simple_serial.h to events.h. Then I put an include statement into simple_serial.c for events.h.

I decided this was a good point to build to see if I had broken anything. It failed to build.  The error I got was

In file included from simple_serial.c:22:0:
../include/events.h:14:1: error: 'task_handler' used but never defined [-Werror]
 task_handler(os_event_t *);
 ^

The LOCAL keyword was making task handler only available to events.c.  I removed the LOCAL keyword from both events.h and events.c and got a new error.

user/.output/eagle/debug/lib/libuser.a(events.o):(.irom0.text+0x2c): undefined reference to `os_sprintf'

It looks like eclipse did not report an error when I removed one of the include lines.  I went back and added one of them at at time till the error went away.  The missing include was osapi.h  The code built and I tested it on the board. It booted and connected to the wifi as expected.

Next I created some macros that I will use when posting a task for serial events.  Now serial_init() is much easier to understand.

Next, I took on simple_config_ui().  First I started by looking at the biggest case statement which had another switch/case statement enclosed. When menu_stat is equal to IDLE, there is a switch/case for handling received characters;  I created a function called recv_byte(char recvd), copied the code and made a few little changes to make it compile and run.  I continued this process of taking large chunks of code and putting them into functions.

Finally I created a new uart.c and moved the code I originally got from uart.c out of simple_serial.c into uart.c. It took a little fiddling to get it all working again.  I have uploaded this update to Github.  Click the firmware link near the top of the right hand column to download it.

Are you cleaning up code? Did you learn to write “easy to read” code in school? How did you learn to write code? Are you learning to write code now?

More code cleanup

I spent the time on this project this week cleaning up the code to match code style and better documentation.  Boring things just have to be done.  I would say in most projects, that approximately 50% of my time is spent on stuff that needs to get done but I don’t enjoy doing.  If you get a good team, this percentage can be reduced.  For instance, some software developers enjoy and even find fascinating the stuff I find boring and tedious.  So if you have a team that is well filled out, then each person gets to work on the stuff he finds interesting.

There will always be some areas that need to be done that no one on your team finds interesting to do and it will just have to get done.  It can be assigned, or just fall to the most relevant team member.  Sometimes the task is shared.

Of course for the Uprogrammer project, I am the “team”.  This means all the tasks (boring or otherwise) fall to me.

This week I worked on the following files.

gpio16.c — reformatted style, no other changes

sigma_delta.c — reformatted style, removed excess comments and dead code

simple_serial.c — reformatted style, skipped editing(big project)

spi_overlap.c — reformatted style, removed excess comments and dead code

SPI.c — reformatted style, removed excess comments and dead code

SPIram.c — reformatted style, removed excess comments and dead code

After all these changes, the code still compiled with no errors or warnings. This is all I had time for this week. I have uploaded these changes to GitHub. Use the link at the top of the right column to download it.  No version change, no functional changes.

I would love to have help on this project. Do you find this project interesting? I could use help in all aspects of this project especially firmware development.  Would you like to be a developer on this project? What parts of this project do you find interesting?

Code Documentation Firmware V00J

I Know that my code is very poorly documented.  So I want to focus on organizing and documenting the code.  To start with, I started looking for online classes that teach documenting code.

I found very little about commenting code.  I did find an interesting article I need to think about a bit more. The general theme of this article is to write code in such a way that comments should be rare.  For instance, code should probably be re-written if it needs comments to explain it. Variables should be named in a way that describes what they contain.

I was just about to give up searching. I was thinking I would start by putting header comments before each function or method.  This article gives pretty good reasoning not to do that. So this week, I decided to look at just one file — user_main.c.  Git does line by line version control.  I decided on one small header block at the beginning of the file.  This header block will indicate the license, original author, and/or the template source.

I looked to the header comments to know what to pass to and get back from a given function.  I have decided to make a new document that describes in better detail how to use each function.  This new file will be called UprogrammerFunctions.txt.  Since I removed the Comment block from in front of user_rf_cal_sector_set, That is the first function I am documenting in the API.

There is a big block of code in user_init() that all it does is set up the IOs to their initial states.  I copied that code into a new function called setup_io_pins() at the end of the user_main.c file. Next, I deleted all the test code I had commented out.  Finally, I made a couple of macros in user_config.h called VOLTAGE_BOOST_ENABLE()  and another one called VOLTAGE_BOOST_DISABLE()

Note: My definition of a macro is the use of a symbolic reference to represent other code.  In this place, I am using VOLTAGE_BOOST_ENABLE()  to represent  gpio16_output_set(0) to make it a little more clear what is going on. I also created a function in wifi.c to set up the wifi modem called wifi_init() and also put a prototype of wifi.init() in wifi.h.  I then moved the two wifi calls out of user_init() into the function wifi_init().

I tried to build and the call to the new function setup_io_pins() caused a linker error.  I needed to create a prototype of this function. I put it in user_config.h and it compiled, I uploaded it and it ran just like before I started cleaning up the code. I believe my user_main.c file is much more readable now.  I have uploaded the new version to GitHub. Click the firmware link in the right column of this page to go look at it or download it.

I would like to hear about your experiences cleaning up and commenting code.  What are your preferences for commenting code.

New Release of Espressif’s SDK (Firmware Version 00I)

Espressif released a new version of their NonOs SDK.  The new Version is 2.0.0 released on July 19, 2016.  The change from 1. something to 2. suggests it might break the code.  I downloaded the new version.

Last week I crippled the software for debugging purposes. I found the bug. This week I want to update to the new version of the SDK.  Since it might break my code, I want to get all the functionality back in the code before I move to the new SDK.

First, I uncommented the HSPI overlap test code. I made a small change to the code that reads out from the SPI RAM to guarantee there is a null terminator in the 13th position of the buffer that is filled from the SPI  RAM. Then I compiled and tested it. It immediately crashed.  I am really glad I haven’t upgraded the SDK yet.

I put hspi_overlap_deinit(); directly after the call to the writeRam(); function. It didn’t crash, but I didn’t get the Hello World from the SPI RAM.  I need to init and deinit hspi overlap mode in the writeRam() and readRam() functions. I modified these two functions and tried again.  Now I get the Hello World after the menu after a reset.

Next, I enabled the WiFi modem.  I set the wifi opmode to  STATION_MODE and commented out the other lines that disabled the modem. It booted, I set the SSID and Password, requested a connect and no apparent result.  I remembered the WiFi Callback is still disabled, I uncommented that and tried again. This time, it remembered the settings from the previous try and connected immediately.

Next, I re-enabled the Sigma Delta circuit and tried changing values.  It is working without crashing.  The code is where it should have been before the buffer overrun bug.  I am ready to upgrade the build environment.

I am going to use this code as my base going forward because the web server code was unstable, and I don’t want to work with the web protocols as much as that would require.

I did some of these tests while the file was downloading from Espressif’s website.  I ran make with the clean option. This removes all the intermediary files used in compiling. Next, I copied the folder I was working with to UProgrammer-SDK1.5.4  This gives me something to go back to if the upgrade fails.  Next I opened up the zip archive of the new SDK.  I copied all the files and folders in the ESP8266_NONOS_SDK into the UProgrammer folder.  This copies over all the SDK files but leaves all my files in place.  It does mean the linker file I modified will get overwritten as well.  I checked this file and they have changed it in the new version of the SDK.  It doesn’t match my linker file, but it might have enough room for my code.  I decided to try compiling without modifying the linker file.

There are linker errors but they are not based on code size.  They describe undefined references to user_rf_cal_sector_set in function flash_data_check.  This looks like a makefile error.  I compared the makefile in the app directory with the one in my project directory.  There was no makefile in the app directory like there has been in previous versions of the SDK.  I went into the examples folder and used the makefile from the IOT_Demo Example for my comparison.  I did some clean up and made some changes to make the files closer to each other.

The changes I made weren’t enough, So I copied the whole file over to see if it fixed it. It didn’t, It looks like a file library file isn’t being linked in. I went into the lib directory looking for the library I needed to link. user_rf_cal_sector_set sounds like a memory function to me. So I looked for a library that dealt with calibration memory.  In the include directory, used the following command line:

grep -r user_rf_cal_sector *

and I got no results back, so for a sanity check, I tried the following command:

grep -r smartconfig *

and I got a list of lines with smartconfig  listed.

On a hunch, I decided to remove the link to main. In the makefile under LINKFLAGS, I removed the line -lmain \.

That also didn’t work.  I did the following command in the UProgrammer foler:

grep -r user_rf_cal_sector *

The result looks like every example implements this function. So I copied that function into user_main.c from the IOT_Demo user_main.c and it turns out they required this new function because they changed the layout of the flash calibration data. Now it builds.  Now the code no longer works.

I tried changing the ld file back to having a length of 0xC0000 and I noticed that the build said I should upload the code to 0x10000.  My shell scripts upload the code to 0x40000.  So, I restored my makefile from the copy of the folder and tried again. It still builds to load at address 0x10000. I modified my script file to load to that location.

And finally, success.  I set the SSID and the password and requested a connect. it seemed to stall.  I reset the board and it connected immediately. I am going to have to take a look at that.

I tested the Sigma Delta and that worked as expected. I measured 22 volts on the output with a duty of 102 and Prescaler of 4.

I re-uploaded the default settings and tried again. I set the SSID, Password, and requested a connect. it seemed to stall again.  I waited ten minutes to see if something would change.  I looked at the connect request code while I was waiting.  Somewhere along the development I deleted the actual call to connect.  I didn’t make it to the full ten minutes. Put the connect request in the code, compiled it, reset the flash to defaults, and uploaded the new version.

This time it connected in about 5 seconds. Success. I have uploaded the new version of the code to GitHub, click the Firmware on GitHub link at the top of the right column to go get it or just take a look.

Please comment below about your experiences upgrading to a new version of API/APK.  Maybe you have had similar experiences switching between devices in a processor family?  I would love to hear from you.

TAPR Open Hardware License (OHL)

The TAPR Open Hardware License (OHL) is the only license I am considering that is written specifically for hardware and patent law.  It requires that any derivative works be licensed the same.  It requires distribution of all modified works to include the originals unmodified.


 

This license restricts what a developer can do with the design.  I am hoping that this product has enough value to developers that they would contribute to the design.  With that premise, I would not like other developers to be limited significantly on how they can use the intellectual property.

I am going to use the MIT license for both hardware and software.  I don’t need patent/copyright protection on this product.  Liability protection is a good thing, I intend this product to be “hackable”. Anything submitted to this blog for product design will be considered under the MIT license unless noted otherwise.

Creative Commons

There are several flavors of the Creative Commons license.  I am going to look at the attribution and attribution share alike licenses.

Both licenses are very similar to the modified BSD license and are more explicit about what rights are conveyed by the license. Both require attribution to the author without endorsement from the author.

The share alike requires any derivative works be licensed with the same license or a compatible one.


For this project, I don’t see any advantage this gives me for the final product.  I hope to build and sell these programmers, but if someone else does for a decent price, I would still benefit.

I have to pick a license or make it public domain or someone else could license or patent it in a way that would restrict me or anybody else from building and selling it.

I am applying common design principals in this project. I do not believe there will be anything unique enough to patent.

MIT License applied to hardware

The MIT license gives a lot of freedom to developers to use the intellectual property in any way they want.  This includes manufacturing, selling, and modifying the design. It does not require or restrict attribution. It does give the designer some protection for liability.  This is not compatible with more restrictive licenses.


The reasons I want to design this product include:

  • Teaching about electronics design
  • Create a low cost universal In Circuit Chip programmer

If some company picks up this design and produces it at a fair price then both objectives are met. This would create a well documented hackable device for a very reasonable price.

The MIT license for software and hardware is compatible with my goals.

If I want to integrate some other design with more a restrictive license, I would have to switch to the more restrictive license or separate the other design into a module or in the case of software a library.

I will continue to look at other software and hardware licenses.

Don’t reinvent the wheel

There are a lot of hardware and software designs that can be used for your own project. Sometimes this design may fit your needs without any modifications. Of course you could also end up spending more time modifying the design than you would have spent designing it yourself.

Research is important when deciding whether or not to use designs developed by someone else. It is important to look at licensing to decide if the license is compatible with your license choices. Readability and documentation are also important factors in the decision.

If you have the budget, you can buy the design.  There is also public domain and open source designs to choose from as well.


This project is not very exotic.  There is probably a lot of free and open source designs available that I will be able to incorporate into the design, especially in the software. I still haven’t decided on the licensing for this project.  There are several common open source licenses for software and probably similar hardware licenses.