diff --git a/README.md b/README.md
index 6a944d8..4c6e165 100644
--- a/README.md
+++ b/README.md
@@ -1,15 +1,23 @@
# ucxclient
+
This repo contains a small footprint AT command client for talking to the following u-blox u-connectXpress short-range modules:
+
* NORA-W36.
-There are two levels of APIs included in this repo; the lower [uAtClient API](#uatclient-api) and the upper [u-connectXpress API](#u-connectXpress-api)
+The client can run on both bare-metal and OS systems using a tiny porting layer (see [Porting and Configuration](#porting-and-configuration))
+
+There are two levels of APIs included in this repo; the lower [uAtClient API](#uatclient-api) and the upper [u-connectXpress API](#u-connectxpress-api).
+
+If you need even more features you can checkout [ubxlib](https://github.com/u-blox/ubxlib) which uses the ucxclient for communicating with the new u-connectXpress modules.
**Please note: The code in this repo is in experimental status and changes to the APIs are to be expected.**
## uAtClient API
+
This API contains an AT client implementation that handles transmission of AT commands, reception and parsing of AT responses and URCs. You will find the uAtClient API in the [inc/](inc) directory.
### Example
+
```c
#include "u_cx_at_client.h"
@@ -34,8 +42,8 @@ void main(void)
.pUrcBuffer = &urcBuf[0],
.urcBufferLen = sizeof(urcBuf),
.pStreamHandle = NULL,
- .write = uCxAtWrite,
- .read = uCxAtRead
+ .write = myWriteFunction,
+ .read = myReadFunction
};
uCxAtClient_t client;
@@ -72,11 +80,13 @@ void main(void)
```
## u-connectXpress API
+
This API is a higher level API that that simplifies communication with new u-connectXpress u-blox modules (only NORA-W36 at the moment).
Using this API eliminates the need of manually sending AT commands to the module.
You will find the u-connectXpress API in the [ucx_api/](ucx_api) directory.
### Example
+
```c
#include "u_cx_at_client.h"
#include "u_cx.h"
@@ -107,20 +117,40 @@ void main(void)
```
## Porting and Configuration
+
All configuration and porting config is located in [inc/u_cx_at_config.h](inc/u_cx_at_config.h).
Make a copy of this file and place it in your code base where you can modify each config to your likings.
When compiling you can specify the name of this local file with `U_CX_AT_CONFIG_FILE` (for GCC you could pass `-DU_CX_AT_CONFIG_FILE=\"my_u_cx_at_config.h\"`).
### Minimum Porting
-Some things are not required for successfully running the AT client (such as U_CX_PORT_PRINTF for logging, U_CX_AT_PORT_ASSERT), but the following is required:
+
+Some things are not required for successfully running the AT client (such as U_CX_PORT_PRINTF for logging, U_CX_AT_PORT_ASSERT), but the following are required:
| Function | Description |
| -------- | ----------- |
| U_CX_PORT_GET_TIME_MS | Must return a 32 bit timestamp in milliseconds.|
-| read() | Passed as argument to uCxAtClientInit(). Should read data from UART with a timeout in millisec. Must return the number of bytes received, 0 if there is no data available within the timeout or negative value on error. |
-| write() | Passed as argument to uCxAtClientInit(). Should write data to the UART. Must return the number of actual bytes written or negative number on error. |
+| read() | Passed as argument to uCxAtClientInit(). Should read data from UART with a timeout in millisec. Must return the number of bytes received, 0 if there are no data available within the timeout or negative value on error. |
+| write() | Passed as argument to uCxAtClientInit(). Should write data to the UART. Must return the number of actual bytes written or negative number on error. |
+
+For systems running RTOS you will also need to port the mutex API below - for bare-metal systems you can use [examples/port/u_port_no_os.h](examples/port/u_port_no_os.h):
+
+| Define | Example (Posix) | Description |
+| -------- | --------------- | ----------- |
+| U_CX_MUTEX_HANDLE | `pthread_mutex_t` | Define this to the mutex type of your system. |
+| U_CX_MUTEX_CREATE(mutex) | `pthread_mutex_init(&mutex, NULL)` | If your system need to call a function before the mutex can be used, then define it here. |
+| U_CX_MUTEX_DELETE(mutex) | `pthread_mutex_destroy(&mutex)` | If your system has a function to de-allocate a mutex, then define it here. |
+| U_CX_MUTEX_LOCK(mutex) | `pthread_mutex_lock(&mutex)` | Define this to corresponding "lock"/"take" function of your system. No return value is expected (any return value will be ignored). |
+| U_CX_MUTEX_TRY_LOCK(mutex, timeoutMs) | `uPortMutexTryLock(&mutex, timeoutMs)`1 | Define this to a function that tries to lock/take the mutex but with a timeout `timeoutMs` in millisec. Must return 0 if the mutex is successfully taken/locked and can return any negative value on timeout. |
+| U_CX_MUTEX_UNLOCK(mutex) | `pthread_mutex_unlock(&mutex)` | Define this to corresponding "unlock"/"give" function of your system. No return value is expected (any return value will be ignored). |
+
+1 See [examples/port/u_port_posix.c](examples/port/u_port_posix.c)
+
+### Example Ports
+
+You will find some example ports in [examples/port](examples/port). These ports are used by the [example code](examples/README.md) and you will find more information in [examples/port/README.md](examples/port/README.md)
+
+## Disclaimer
-# Disclaimer
Copyright © u-blox
u-blox reserves all rights in this deliverable (documentation, software, etc.,
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..3af38c7
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,63 @@
+# Examples
+
+This directory contains application examples of how to use ucxclient. The examples make use of the [example ports](port/README.md).
+
+| Files | Description |
+| -------------------- | ----------- |
+| http_example.c | Example of doing a HTTP GET request using the uCx API. |
+| http_example_no_os.c | Same example as http_example.c but illustrating how it could be done on a bare-metal system with no OS. |
+
+## Building
+
+To build all the examples on a Linux based system, just execute the following in repo root if you prefer Makefile:
+
+```sh
+> cmake -S . -B build -G "Unix Makefiles"
+> make -C build
+```
+
+or if you prefer Ninja:
+
+```sh
+> cmake -S . -B build -G "Ninja"
+> ninja -C build
+```
+
+## Running
+
+### http_example
+
+If you have built http_example using the steps above it will be built for Linux and located in `build/http_example`.
+To start it you will need to pass some arguments:
+
+```
+http_example
+ device: the UART device that is connected to a u-connectXpress module
+ SSID: the Wi-Fi SSID to connect to
+ WPA_PSK: the Wi-Fi WPA PSK
+```
+
+Example:
+
+```sh
+> build/http_example /dev/ttyUSB0 MySSID MyWiFiPasswd
+```
+
+### http_example_no_os
+
+Just like http_example this example will also be compiled for Linux, but in this case the UART device, Wi-Fi SSID and PSK are configured using defines.
+To set these defines using CMake you can either use `cmake-gui`:
+
+
+
+or from command line:
+
+```sh
+> cmake -S . -B build -D U_EXAMPLE_UART="/dev/ttyUSB0" -D U_EXAMPLE_SSID="MySSID" -D U_EXAMPLE_WPA_PSK="MyWiFiPasswd"
+```
+
+Now you should be able to start the example using:
+
+```sh
+> build/http_example_no_os
+```
diff --git a/examples/http_example.c b/examples/http_example.c
index 766adf5..ee2caa1 100644
--- a/examples/http_example.c
+++ b/examples/http_example.c
@@ -15,7 +15,7 @@
*/
/** @file
- * @brief Linux example for doing HTTP GET request using NORA-W36
+ * @brief Example of how to do a HTTP GET request using the uCx API
*
* This example will:
* - Setup WiFi
diff --git a/examples/port/README.md b/examples/port/README.md
new file mode 100644
index 0000000..a73561a
--- /dev/null
+++ b/examples/port/README.md
@@ -0,0 +1,22 @@
+# Port Examples
+
+This directory contains example ports that you can either use out-of-box or use as inspiration.
+
+| Files | Description |
+| ------------- | ----------- |
+| u_port.h | A common API mainly for being able to run the [example code](/examples/README.md) using any of the ports. |
+| u_port_posix | A Linux port example using Posix threads. |
+| u_port_no_os | A "no OS" port example to illustrate how ucxclient could be ported to a bare-metal system. The UART and time porting layer is using Linux API for this example so you will need to adjust it for your specific target. |
+| u_port_zephyr | A Zephyr port example. You will find details on how to use it in [/zephyr/README.md](/zephyr/README.md). |
+
+## Using an Example Port
+
+You can tell ucxclient which port to use by using the following defines during build:
+
+| Port | Define |
+| ------------- | -------------- |
+| u_port_posix | `U_PORT_POSIX` |
+| u_port_no_os | `U_PORT_NO_OS` |
+| u_port_zephyr | No define needed; it will be selected automatically if you use ucxclient as a Zephyr module (see [/zephyr/README.md](/zephyr/README.md)). |
+
+You will also need to add corresponding .c file to your build (not needed for Zephyr).
diff --git a/images/cmake-gui.png b/images/cmake-gui.png
new file mode 100644
index 0000000..00aaa09
Binary files /dev/null and b/images/cmake-gui.png differ
diff --git a/zephyr/README.md b/zephyr/README.md
new file mode 100644
index 0000000..2387aba
--- /dev/null
+++ b/zephyr/README.md
@@ -0,0 +1,56 @@
+# Zephyr Module
+
+ucxclient can be used as a Zephyr module for easy integration to your Zephyr application.
+
+## Adding ucxclient to Your Zephyr App
+
+There are several ways of including ucxclient to your Zephyr application.
+
+### Using `west.yml` manifest
+
+If you use a `west.yml` manifest for your application then you can add ucxclient as to the list of projects like this:
+
+```yml
+manifest:
+ remotes:
+ - name: zephyrproject-rtos
+ url-base: https://github.com/zephyrproject-rtos
+ - name: u-blox
+ url-base: https://github.com/u-blox
+
+ projects:
+ - name: zephyr
+ remote: zephyrproject-rtos
+ revision: main
+
+ - name: ucxclient
+ remote: u-blox
+ repo-path: ucxclient.git
+ revision: master
+```
+
+There is a very useful Zephyr example app illustrating how to create folder structure etc for a Zephyr application using a `west.yml` manifest file available here:
+[https://github.com/zephyrproject-rtos/example-application](https://github.com/zephyrproject-rtos/example-application)
+
+### Using `ZEPHYR_MODULES` CMake Variable
+
+With this method you need to clone ucxclient manually or use git submodule or similar.
+After that you need to add the path of ucxclient to the `ZEPHYR_MODULES` CMake variable.
+This can be done in several ways as described here:
+[https://docs.zephyrproject.org/latest/develop/modules.html#without-west](https://docs.zephyrproject.org/latest/develop/modules.html#without-west)
+
+## Config
+
+To build ucxclient with your Zephyr application you must add the following to your `prj.conf`:
+
+```ini
+CONFIG_SERIAL=y
+CONFIG_UART_INTERRUPT_DRIVEN=y
+CONFIG_RING_BUFFER=y
+CONFIG_UCXCLIENT=y
+```
+
+The current Zephyr port only support the interrupt driven UART API.
+
+Further configuration of ucxclient are also possible.
+Use [menuconfig](https://docs.zephyrproject.org/latest/build/kconfig/menuconfig.html) to view and configure these.