Summary

This is the first article in a series about my journey implementing PSoC 6 SDK libraries for the Maxxim One Wire Bus and the DS18B20 temperature sensor.

As you can see there will be many parts to this story:

Story

I recently got a twitter message from a gentleman named “Neeraj Dhekale”.  He asked about a library for a one wire sensor for PSoC, actually to be specific he asked about a component for a PSoC 4.

Then I asked him what sensor and responded that he wanted to use the Maxxim DS18B20 temperature sensor.

This sensor is a one wire temperature sensor, here is a bit of snapshot from the data sheet.

After reading the data sheet I decided that I really didn’t want to implement a complete library for this sensor.  So, I started looking around for a driver library.  After googling around a little bit I found a library on GitHub (https://github.com/DavidAntliff/esp32-ds18b20) which looked promising, even though it is ESP32 specific.

But, after looking at this GitHub library a bit, I decide to start from there.

Before I get started two comments.

  1. He asked for PSoC 4 … but I am going to do PSoC 6 (because I can use Modus Toolbox).  There is no reason why this wouldn’t work on PSoC 4 – but it would take a bit of work
  2. I can’t think of a good reason to use 1-wire, it sure seems like I2C would be simpler

Build a Base Project

I start this whole effort by creating a new project for the CY8CKIT-062S2-43012 (because that happens to be the kit on my desk at the moment)

I will use the IoT Expert FreeRTOS Template project

For debugging this whole thing I will use a command line shell.  To get this into the project I add the ntshell library. Run “make modlibs” to start the library manager.

In the library manager pick the “ntshell” library

To develop this project I want to use Visual Studio code.  So, I run “make vscode” (to create the configuration files) and start vscode by running “code .”

When VSCODE starts up it looks like this:

In order to use the ntshell library you need to shuffle the files around a little bit.  Move the ntshell.h/.c into the main project by doing a drag/drop in the explorer window.

It will ask you really want to move the files

Once it is done, the ntshell functions which you need to customize will be part of the project.

To use the ntshell, you need to add the task to main.c

#include "cy_pdl.h"
#include "cyhal.h"
#include "cybsp.h"
#include "cy_retarget_io.h"
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"

#include "ntshell.h"
#include "ntlibc.h"
#include "psoc6_ntshell_port.h"

// Global variable with a handle to the shell
ntshell_t ntshell;

void ntShellTask()
{

  printf("Started ntshell\n");
  setvbuf(stdin, NULL, _IONBF, 0);
  ntshell_init(
	       &ntshell,
	       ntshell_read,
	       ntshell_write,
	       ntshell_callback,
	       (void *)&ntshell);
  ntshell_set_prompt(&ntshell, "DS18B20> ");
  vtsend_erase_display(&ntshell.vtsend);
  ntshell_execute(&ntshell);
}

And start the task

    xTaskCreate(ntShellTask, "nt shell task", configMINIMAL_STACK_SIZE*2,0 /* args */ ,0 /* priority */, 0);

Build and compile

And you should have a working project.

Run “make program” to get the board going

arh (master *) OWB_DS18B20 $ make program
Tools Directory: /Applications/ModusToolbox/tools_2.1
Prebuild operations complete
Commencing build operations...
Tools Directory: /Applications/ModusToolbox/tools_2.1
Initializing build: mtb-example-psoc6-empty-app Debug CY8CKIT-062S2-43012 GCC_ARM
Auto-discovery in progress...
-> Found 202 .c file(s)
-> Found 50 .S file(s)
-> Found 27 .s file(s)
-> Found 0 .cpp file(s)
-> Found 0 .o file(s)
-> Found 4 .a file(s)
-> Found 450 .h file(s)
-> Found 0 .hpp file(s)
-> Found 0 resource file(s)
Applying filters...
Auto-discovery complete
Constructing build rules...
Build rules construction complete
==============================================================================
= Building application =
==============================================================================
Building 181 file(s)
==============================================================================
= Build complete =
==============================================================================
Calculating memory consumption: CY8C624ABZI-D44 GCC_ARM -Og
---------------------------------------------------- 
| Section Name         |  Address      |  Size       | 
---------------------------------------------------- 
| .cy_m0p_image        |  0x10000000   |  5972       | 
| .text                |  0x10002000   |  49532      | 
| .ARM.exidx           |  0x1000e17c   |  8          | 
| .copy.table          |  0x1000e184   |  24         | 
| .zero.table          |  0x1000e19c   |  8          | 
| .data                |  0x080022e0   |  1688       | 
| .cy_sharedmem        |  0x08002978   |  8          | 
| .noinit              |  0x08002980   |  148        | 
| .bss                 |  0x08002a14   |  985176     | 
| .heap                |  0x080f3270   |  46480      | 
---------------------------------------------------- 
Total Internal Flash (Available)          2097152    
Total Internal Flash (Utilized)           59468      
Total Internal SRAM (Available)           1046528    
Total Internal SRAM (Utilized)            1033500    
Programming target device... 
Open On-Chip Debugger 0.10.0+dev-3.0.0.665 (2020-03-20-17:12)
Licensed under GNU GPL v2
For bug reports, read
http://openocd.org/doc/doxygen/bugs.html
Info : auto-selecting first available session transport "swd". To override use 'transport select <transport>'.
adapter speed: 2000 kHz
** Auto-acquire enabled, use "set ENABLE_ACQUIRE 0" to disable
cortex_m reset_config sysresetreq
cortex_m reset_config sysresetreq
Info : Using CMSIS loader 'CY8C6xxA_SMIF' for bank 'psoc6_smif0_cm0' (footprint 6485 bytes)
Warn : SFlash programming allowed for regions: USER, TOC, KEY
Info : CMSIS-DAP: SWD  Supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 1 SWDIO/TMS = 1 TDI = 0 TDO = 0 nTRST = 0 nRESET = 1
Info : CMSIS-DAP: Interface ready
Info : KitProg3: FW version: 1.11.159
Info : KitProg3: Pipelined transfers disabled, please update the firmware
Warn : *******************************************************************************************
Warn : * KitProg firmware is out of date, please update to the latest version using fw-loader at *
Warn : * ModusToolbox/tools/fw-loader                                                            *
Warn : *******************************************************************************************
Info : VTarget = 3.263 V
Info : kitprog3: acquiring PSoC device...
Info : clock speed 2000 kHz
Info : SWD DPIDR 0x6ba02477
Info : psoc6.cpu.cm0: hardware has 4 breakpoints, 2 watchpoints
Info : psoc6.cpu.cm0: external reset detected
***************************************
** Silicon: 0xE402, Family: 0x102, Rev.: 0x11 (A0)
** Detected Device: CY8C624ABZI-S2D44A0
** Detected Main Flash size, kb: 2048
** Flash Boot version: 3.1.0.45
** Chip Protection: NORMAL
***************************************
Info : psoc6.cpu.cm4: hardware has 6 breakpoints, 4 watchpoints
Info : psoc6.cpu.cm4: external reset detected
Info : Listening on port 3333 for gdb connections
Info : Listening on port 3334 for gdb connections
Info : kitprog3: acquiring PSoC device...
target halted due to debug-request, current mode: Thread 
xPSR: 0x41000000 pc: 0x00000190 msp: 0x080ff800
** Device acquired successfully
** psoc6.cpu.cm4: Ran after reset and before halt...
target halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x0000012a msp: 0x080ff800
** Programming Started **
auto erase enabled
Info : Flash write discontinued at 0x10001754, next section at 0x10002000
Info : Padding image section 0 at 0x10001754 with 172 bytes (bank write end alignment)
[100%] [################################] [ Erasing     ]
[100%] [################################] [ Programming ]
Info : Padding image section 1 at 0x1000e844 with 444 bytes (bank write end alignment)
[100%] [################################] [ Erasing     ]
[100%] [################################] [ Programming ]
wrote 57856 bytes from file /Users/arh/proj/xxx/OWB_DS18B20/build/CY8CKIT-062S2-43012/Debug/mtb-example-psoc6-empty-app.hex in 2.294771s (24.621 KiB/s)
** Programming Finished **
** Verify Started **
verified 57240 bytes in 0.155447s (359.598 KiB/s)
** Verified OK **
** Resetting Target **
shutdown command invoked
arh (master *) OWB_DS18B20 $

And you should have a working project (with a blinking led and a command line)

Add the DS18B20 Library

Now that I have a working project the next step is to clone the DS18B20 library into my project.  This is done using

  • git clone https://github.com/DavidAntliff/esp32-ds18b20

The next step is to establish how bad things are with the new library.  So run the compiler.

When I look at the ds18b20.c file I can see that there are some obvious problems

#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_system.h"
#include "esp_log.h"
#include "ds18b20.h"
#include "owb.h"

Fix those:

#include "FreeRTOS.h"
#include "task.h"
//#include "driver/gpio.h"
//#include "esp_system.h"
//#include "esp_log.h"
#include "ds18b20.h"
//#include "owb.h"

Run the compiler again.  Now I am missing owb.h which is the public header file for the one wire bus.

In file included from esp32-ds18b20/ds18b20.c:47:0:
./esp32-ds18b20/include/ds18b20.h:37:10: fatal error: owb.h: No such file or directory
#include "owb.h"

I now make a directory to hold the new owb files called “p6sdk-onewire”.  Then I add a file “owb.h” (as a blank file)

When I run the compiler again, there are now two classes or error … owb and esp32 logging function. Here is an example of the ESP_ problems.

esp32-ds18b20/ds18b20.c:249:17: warning: implicit declaration of function 'ESP_LOG_BUFFER_HEX_LEVEL' [-Wimplicit-function-declaration]
ESP_LOG_BUFFER_HEX_LEVEL(TAG, scratchpad, count, ESP_LOG_DEBUG);
^~~~~~~~~~~~~~~~~~~~~~~~
esp32-ds18b20/ds18b20.c:249:66: error: 'ESP_LOG_DEBUG' undeclared (first use in this function)
ESP_LOG_BUFFER_HEX_LEVEL(TAG, scratchpad, count, ESP_LOG_DEBUG);

And here is an example of the owb problems.

esp32-ds18b20/ds18b20.c: In function 'ds18b20_wait_for_conversion':
esp32-ds18b20/ds18b20.c:504:30: error: request for member 'use_parasitic_power' in something not a structure or union
if (ds18b20_info->bus->use_parasitic_power)
^~
esp32-ds18b20/ds18b20.c: At top level:
esp32-ds18b20/ds18b20.c:568:54: error: unknown type name 'OneWireBus'
DS18B20_ERROR ds18b20_check_for_parasite_power(const OneWireBus * bus, bool * present)
^~~~~~~~~~
esp32-ds18b20/ds18b20.c: In function 'ds18b20_check_for_parasite_power':
esp32-ds18b20/ds18b20.c:577:44: error: 'OWB_ROM_SKIP' undeclared (first use in this function); did you mean 'CY_ROM_SIZE'?
if ((err = owb_write_byte(bus, OWB_ROM_SKIP)) == DS18B20_OK)
^~~~~~~~~~~~
CY_ROM_SIZE
make[1]: *** [/Users/arh/proj/xxx/OWB_DS18B20/build/CY8CKIT-062S2-4301

To make this thing go, I edit ds18b20.c file and add logging templates (just stub functions that don’t do anything)

void ESP_LOGD(const char * code, char *val,...)
{
}
void ESP_LOGE(const char * code, ...)
{
}
void ESP_LOGW(const char *code,...)
{
}
#define ESP_LOG_DEBUG 0
void ESP_LOG_BUFFER_HEX_LEVEL(const char *code,...)
{
}
uint64_t esp_timer_get_time()
{
return 0;
}

Create owb.h

If I was smart, I would have started with David Antliff “owb” library.  But I don’t.  What I do is search through “ds18b20.c” and find every function call to owb_ and then copy those function calls into owb.h (my new file).  Then I fix the function calls to have correct prototypes based on what I see in the ds18b20 library.  Here is what my owb.h file looks like after that process.

#ifndef OWB_H
#define OWB_H
#ifdef __cplusplus
extern "C" {
#endif
#define OWB_ROM_MATCH 0
#define OWB_ROM_SKIP 0
#include <stdint.h>
#include "cyhal.h"
#include "FreeRTOS.h"
#include "semphr.h"
typedef struct  
{
cyhal_gpio_t  pin;
bool use_parasitic_power;
SemaphoreHandle_t signalSemaphore;
cyhal_timer_t bitTimer;
bool detect;
SemaphoreHandle_t owb_num_active;
} OneWireBus;        
typedef struct {
uint8_t romAddr[8];
} OneWireBus_ROMCode;
typedef enum {
OWB_STATUS_OK,
OWB_STATUS_ERROR,
} owb_ret_t ;
owb_ret_t owb_init(OneWireBus *bus);
owb_ret_t owb_reset(OneWireBus *bus, bool *result);
owb_ret_t owb_write_bit( OneWireBus *bus, uint8_t val);
owb_ret_t owb_write_byte( OneWireBus *bus, uint8_t val);
owb_ret_t owb_write_bytes( OneWireBus *bus, uint8_t *buffer, uint32_t length);
owb_ret_t owb_write_rom_code(OneWireBus *bus, OneWireBus_ROMCode romcode);
owb_ret_t owb_read_bit( OneWireBus *bus, uint8_t *bit);
owb_ret_t owb_read_byte( OneWireBus *bus, uint8_t *byte);
owb_ret_t owb_read_bytes( OneWireBus *bus, uint8_t *buffer, uint32_t length);
owb_ret_t owb_crc8_bytes(uint32_t val, uint8_t *buffer, uint32_t length);
void   owb_set_strong_pullup( OneWireBus *bus, bool val);
#endif
#ifdef __cplusplus
}
#endif

When I run the compiler again things look way better (just some complaining about const datatypes) and a complaint about the include path.  The include path thing is visual studio code not knowing that I added a new directory called p6sdk-onewire.

To fix the include path I run “make vscode” which tells VSCODE about the new directory.

That is a good place to split this article.  In the next article I will add functions to read and write the bus.

Recommended Posts

No comment yet, add your voice below!


Add a Comment

Your email address will not be published. Required fields are marked *