Clicking on any link opens an HTML page with the program. 

Right click on page and use view source to see code.

Use inspect to see any additional JavaScript loaded. 

Part I

Chapter 2

Page 20 Page 21

Chapter 3

Page 26    Page 28    Page 30 Page 33 Page 34  Page 38  Page 47  Page 49 

Chapter 4

Page 55 Page 57 Page 59 Page 61 Page 63  Page 67  Page 69  Page 70  Page 71  Page 72  Page 73  Page 74  Page 74b  Page 76 

Chapter 5

Page 81  Page 85  Page 86  Page 87  Page 89

Chapter 6

Page 96 Page 97 Page 104

Chapter 7

Page 110 Page 118 Page 126

Part II

Chapter 8

Page 130 Page 132 Page 134 Page 139 Page 140 Page 140b Page 141 Page 145 Page 148 Page 149

Chapter 9

Page 162  Page 165  Page 168  

Chapter 12

Page 201   Page 205   Page 205b   Page 206   Page 208   Page 214  

The file upload examples are listed as text files to avoid priviacy and security issues. 
(IO Press cannot host files users upload without conforming to the GDPR)

Page 216 (text)   Page 217 (text)  Page 218 (text)  Page 219 (text)  Page 221 (text)  Page 222 (text)  Page 224  

Chapter 13

Page 229   Page 230   Page 231  Page 235  Page 239  Page 246

You can use pond.pcx to test the PCX program, page 246. Download it to a suitable directory and then use at as a local file to be processed.

Chapter 14

Page 257 This is the program that starts being built up on page 257 and finishes at page 265 Page 270

Chapter 15

Page 275  Page 285  Page 290  Page 293  Page 298  

Micro:bit IoT In C Second Edition

microbite2360

 

We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.

The best solution is to provide the source code of the programs in a form that can be copied and pasted into a NetBeans of VS Code project. 

The only downside is that you have to create a project to paste the code into.

To do this follow the instructions in the book.

All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book. This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.

If anything you consider important is missing or if you have any requests or comments  contact:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 29

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE);
    for (;;)
    {
        uBit.display.image.setPixelValue(2, 2, 255);
        uBit.sleep(1000);
        uBit.display.image.setPixelValue(2, 2, 0);
        uBit.sleep(1000);
    }
}

 

Page 38 

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.io.P0.setDigitalValue(1);
}

#include "MicroBit.h"
    int main()
{
    MicroBitPin P0(MICROBIT_ID_IO_P0, MICROBIT_PIN_P0,
                   PIN_CAPABILITY_ALL);
    P0.setDigitalValue(1);
}

Page 44

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        uBit.io.P0.setDigitalValue(0);
    }
}

Page 45

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        uBit.sleep(9);
        uBit.io.P0.setDigitalValue(0);
        uBit.sleep(9);
    }
}

Page 46

MicroBit uBit;
int main()
{
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        wait_us(20);
        uBit.io.P0.setDigitalValue(0);
        wait_us(20);
    }
}

Page 46

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    int i;
    int n = 57;
    while (1)
    {
        for (i = 0; i < n; i++)
        {
        };
        uBit.io.P0.setDigitalValue(1);
        for (i = 0; i < n; i++)
        {
        };
        uBit.io.P0.setDigitalValue(0);
    }
}

Page 47

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    int i;
    uBit.init();
    while (1)
    {
        uBit.io.P0.setDigitalValue(1);
        uBit.io.P1.setDigitalValue(0);
        uBit.io.P0.setDigitalValue(0);
        uBit.io.P1.setDigitalValue(1);
    }
}

Page 49

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    int i;
    uBit.init();
    while (1)
    {
        for (i = 0; i < 100; i++)
        {
        };
        uBit.io.P0.setDigitalValue(1);
        uBit.io.P1.setDigitalValue(0);
        for (i = 0; i < 100; i++)
        {
        };
        uBit.io.P0.setDigitalValue(0);
        uBit.io.P1.setDigitalValue(1);
    }
}

Page 52

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    int i;
    uBit.init();
    while (1)
    {
        while (1 == uBit.io.P0.getDigitalValue())
            ;
        while (0 == uBit.io.P0.getDigitalValue())
            ;
        for (i = 0; i < 1000; i++)
        {
            if (0 == uBit.io.P0.getDigitalValue())
                break;
        }
        uBit.serial.printf("%d\n\r", i);
    }
}

Page 54

#include "MicroBit.h"

MicroBit uBit;
int main()
{
    uBit.init();
    uint64_t t;

    volatile int i;

    while (1)
    {
        while (1 == uBit.io.P0.getDigitalValue())
            ;
        while (0 == uBit.io.P0.getDigitalValue())
            ;
        t = system_timer_current_time_us();
        for (i = 0; i < 1000; i++)
        {
            if (0 == uBit.io.P0.getDigitalValue())
                break;
        }
        t = system_timer_current_time_us() - t;

        uBit.serial.printf("%d,%d\n\r", i, (int)t);
    }
}

Page 56

#include "MicroBit.h"
MicroBit uBit;
uint64_t t[20];
uint64_t temp = 0;
int i = 0;
void onPulseEdge(MicroBitEvent evt)
{
    t[i] = (evt.timestamp - temp);
    i++;
    temp = evt.timestamp;
    if (i < 20)
        return;
    uBit.io.P0.eventOn(MICROBIT_PIN_EVENT_NONE);
}

int main()
{
    uBit.init();
    uBit.messageBus.listen(MICROBIT_ID_IO_P0,
                           MICROBIT_PIN_EVT_RISE,
                           onPulseEdge,
                           MESSAGE_BUS_LISTENER_IMMEDIATE);
    uBit.messageBus.listen(MICROBIT_ID_IO_P0,
                           MICROBIT_PIN_EVT_FALL,
                           onPulseEdge,
                           MESSAGE_BUS_LISTENER_IMMEDIATE);
    uBit.io.P0.eventOn(MICROBIT_PIN_EVENT_ON_EDGE);
}
uBit.sleep(1000);
for (i = 1; i < 20; i++)
{
    printf("%d\n\r", (int)t[i]);
}

Page 63

int main()
{
    int GPIO = 3;
    // GPIO=2; //Uncomment for V2
    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);

    unsigned int mask = 1 << GPIO;
    *dirset = mask;
    for (;;)
    {
        *outset = mask;
        *outclr = mask;
    }
}

Page 64

int main()
{

    int GPIO = 3;
    //GPIO = 2; // Uncomment for V2
    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);
    unsigned int mask = 1 << GPIO;

    *dirset = mask;
    volatile int i;
    int n = 200;
    for (;;)
    {
        for (i = 0; i < n; i++)
        {
        };
        *outset = mask;
        for (i = 0; i < n; i++)
        {
        };
        *outclr = mask;
    }
}

Page 65

int main()
{

    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);

    volatile int i;
    int n = 200;
    unsigned int mask = 1 << 2 | 1 << 3;
    *dirset = mask;
    for (;;)
    {
        *outset = mask;
        for (i = 0; i < n; i++)
        {
        };
        *outclr = mask;
        for (i = 0; i < n; i++)
        {
        };
    }
}

Page 66

int main()
{

    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
    volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);

    volatile int i;
    int n = 200;
    unsigned int mask = 1 << 3 | 1 << 2;
    unsigned int mask1 = 1 << 3;
    unsigned int mask2 = 1 << 2;
    *dirset = mask;
    for (;;)
    {
        *outset = mask1;
        *outclr = mask2;
        for (i = 0; i < n; i++)
        {
        };
        *outclr = mask1;
        *outset = mask2;
        for (i = 0; i < n; i++)
        {
        };
    }
}

Page 67

int main()
{

    volatile unsigned int *dirset = (unsigned int *)(0x50000000UL + 0x518);
    volatile unsigned int *out = (unsigned int *)(0x50000000UL + 0x504);
    volatile int i;
    int n = 200;
    unsigned int mask1 = 1 << 2;
    unsigned int mask2 = 1 << 3;
    *dirset = (1 << 2) | (1 << 3);
    for (;;)
    {
        *out = mask1;
        for (i = 0; i < n; i++)
        {
        };
        *out = mask2;
        for (i = 0; i < n; i++)
        {
        };
    }
}

Page 68

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    int GPIO = 3;
    GPIO = 2; // Uncomment for V2
    volatile unsigned int *in = (unsigned int *)(0x50000000UL + 0x510);
    volatile unsigned int *pinDir =
        (unsigned int *)(0x50000000UL + 0x700 + GPIO * 4);
    unsigned int mask = 1 << GPIO;
    *pinDir = 0x0;
    volatile int i;
    uBit.serial.printf("Ready\n\r");
    while (1)
    {
        while (mask == ((*in) & mask))
        {
        };
        while (mask != ((*in) & mask))
        {
        };
        for (i = 0; i < 5000; i++)
        {
            if (mask != ((*in) & mask))
                break;
        }
        uBit.serial.printf("%d\n\r", i);
    }
    return 0;
}

Page 74

#include "MicroBit.h"

MicroBit uBit;
int main() { 
 uBit.init();
 uBit.io.P0.setAnalogValue(511);
 uBit.io.P0.setAnalogPeriod(1);
 release_fiber();
 return 0;

Page 75

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(200);
    uBit.io.P1.setAnalogValue(511);
    uBit.io.P2.setAnalogValue(800);

    uBit.io.P0.setAnalogPeriod(1);
    uBit.io.P1.setAnalogPeriod(1);
    uBit.io.P2.setAnalogPeriod(1);

    release_fiber();
    return 0;
}

Page 76

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    volatile int i;
    uBit.init();

    uBit.io.P0.setAnalogValue(200);
    uBit.io.P0.setAnalogPeriodUs(50);

    for (;;)
    {
        for (i = 1; i < 100; i++)
        {
        };
        uBit.io.P0.setAnalogValue(200);
        for (i = 1; i < 100; i++)
        {
        };
        uBit.io.P0.setAnalogValue(800);
    }
}

Page 78

#include "MicroBit.h"

//#define wait_us system_timer_wait_us // uncomment for V2
MicroBit uBit;

int main()
{
    int i;
    uBit.init();
    uBit.io.P0.setAnalogValue(200);
    uBit.io.P0.setAnalogPeriodUs(50);
    for (;;)
    {
        for (i = 0; i < 1024; i = i + 10)
        {
            uBit.io.P0.setAnalogValue(i);
            wait_us(100);
        }
    }
    release_fiber();
    return 0;
}

Page 82

#include "MicroBit.h"
//#define wait_us system_timer_wait_us // uncomment for V2
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(511);
    uBit.io.P0.setAnalogPeriodUs(1000);
    int w = 1;
    int inc = 1;
    for (;;)
    {
        uBit.io.P0.setAnalogValue(w);
        w = w + inc;
        if (w > 1024 || w <= 0)
            inc = -inc;
        wait_us(5000);
    }
    release_fiber();
    return 0;
}

Page 83

#include "MicroBit.h"
//#define wait_us system_timer_wait_us // uncomment for V2
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(511);
    uBit.io.P0.setAnalogPeriodUs(1000);

    int w = 0;
    int inc = 1;
    for (;;)
    {
        uBit.io.P0.setAnalogValue(w * w * w);
        w = w + inc;
        if (w > 10 || w <= 0)
            inc = -inc;
        wait_us(50000);
    }
    release_fiber();
    return 0;
}

Page 86

#include "MicroBit.h"

MicroBit uBit;

int main()
{
    uBit.init();
    for (;;)
    {
        uBit.io.P0.setServoValue(0);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(90);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(180);
        uBit.sleep(1000);
    }
    release_fiber();
    return 0;
}

Page 87

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    uBit.io.P0.setAnalogValue(0);
    uBit.io.P0.setAnalogPeriod(20);
    for (;;)
    {
        uBit.io.P0.setAnalogValue(52 * 0 / 180 + 920);
        uBit.sleep(1000);
        uBit.io.P0.setAnalogValue(52 * 90 / 180 + 920);
        uBit.sleep(1000);
        uBit.io.P0.setAnalogValue(52 * 180 / 180 + 920);
        uBit.sleep(1000);
    }
    release_fiber();
    return 0;
}

Page 90

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    for (;;)
    {
        uBit.io.P0.setServoValue(0, 1000);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(90, 1000);
        uBit.sleep(1000);
        uBit.io.P0.setServoValue(180, 1000);
        uBit.sleep(1000);
    }
    release_fiber();
    return 0;
}

Page 102

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    char buf[] = {0x07};
    uBit.i2c.write(0x1C, buf, 1, true);
    uBit.i2c.read(0x1C, buf, 1);
    printf("Id %X\r\n", (int)buf[0]);
    release_fiber();
    return 0;
}

Page 104

#include "MicroBit.h"

#define LSM303_ADDR 0x32
#define LSM303_WHO 0x0F
#define LSM303_VAL 0x33

#define FXOS8700_ADDR 0x3C
#define FXOS8700_WHO 0x0D
#define FXOS8700_VAL 0xC7
MicroBit uBit;

int main()
{
    uBit.init();
    uint8_t data[1];
    int status = 0;

    status = uBit._i2c.readRegister(LSM303_ADDR, LSM303_WHO, data, 1);
    if (data[0] == LSM303_VAL)
        uBit.serial.printf("LSM303 \n\r");

    status = uBit._i2c.readRegister(FXOS8700_ADDR, FXOS8700_WHO, data, 1);
    if (data[0] == FXOS8700_VAL)
        uBit.serial.printf("FXOS8700 \n\r");
    return 0;
}

Page 105

#include "MicroBit.h"

#define LSM303_ADDR 0x32
#define LSM303_WHO 0x0F
#define LSM303_VAL 0x33

#define FXOS8700_ADDR 0x3C
#define FXOS8700_WHO 0x0D
#define FXOS8700_VAL 0xC7
MicroBit uBit;

int main()
{
    uBit.init();
    uint8_t data[2];
    int status = 0;
    uBit.compass.requestUpdate();
    int x = uBit.compass.getX();
    uBit.serial.printf("X %d \n\r", x);
    int y = uBit.compass.getY();
    uBit.serial.printf("Y %d \n\r", y);
    int z = uBit.compass.getZ();
    uBit.serial.printf("Z %d \n\r", z);

    status = uBit._i2c.readRegister(0x3C, 0x68, &data[0], 1);
    status = uBit._i2c.readRegister(0x3C, 0x69, &data[1], 1);
    int16_t X = data[1] << 8 | data[0];
    uBit.serial.printf("X %d \n\r", X);

    status = uBit._i2c.readRegister(0x3C, 0x6A, &data[0], 1);
    status = uBit._i2c.readRegister(0x3C, 0x6B, &data[1], 1);
    int16_t Y = data[1] << 8 | data[0];
    uBit.serial.printf("Y %d \n\r", Y);

    status = uBit._i2c.readRegister(0x3C, 0x6C, &data[0], 1);
    status = uBit._i2c.readRegister(0x3C, 0x6D, &data[1], 1);
    int16_t Z = data[1] << 8 | data[0];
    uBit.serial.printf("Z %d \n\r", Z);

    return 0;
}

Page 111

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uint8_t buf[] = {0xE7};
    uBit.i2c.write(0x80, buf, 1);
    uBit.i2c.read(0x80, buf, 1);
    uBit.serial.printf("User Register = %X \r\n", buf[0]);
    return 0;
}

Page 112

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uint8_t buf[] = {0};
    uBit.i2c.readRegister(0x80, 0xE7, buf, 1);
    uBit.serial.printf("User Register = %X \r\n", buf[0]);
    return 0;
}

Page 114

#include "MicroBit.h"
MicroBit uBit;

int main()
{
    uBit.init();
    uint8_t buf[3] = {0};
    uBit.i2c.readRegister(0x80, 0xE3, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    uBit.serial.printf("msb %d \n lsb %d \n checksum %d \n\r",
                       msb, lsb, check);
    return 0;
}

Page 117

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uint8_t buf[3] = {0};
    uBit.i2c.readRegister(0x80, 0xE3, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];

    unsigned int data16 = ((unsigned int)msb << 8) |
                          (unsigned int)(lsb & 0xFC);
    int temp = -4685 + ((17572 * data16) >> 16);
    uBit.serial.printf("Temperature %d.%d C \n\r",
                       temp / 100, temp % 100);
    return 0;
}

Page 119

uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
    uint32_t data32 = ((uint32_t)msb << 16) |
                      ((uint32_t)lsb << 8) | (uint32_t)check;
    uint32_t divisor = 0x988000;
    for (int i = 0; i < 16; i++)
    {
        if (data32 & (uint32_t)1 << (23 - i))
            data32 ^= divisor;
        divisor >>= 1;
    };
    return (uint8_t)data32;
}

Page 121

#include "MicroBit.h"
MicroBit uBit;

uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
    uint32_t data32 = ((uint32_t)msb << 16) | ((uint32_t)lsb << 8) |
                      (uint32_t)check;
    uint32_t divisor = 0x988000;
    for (int i = 0; i < 16; i++)
    {
        if (data32 & (uint32_t)1 << (23 - i))
            data32 ^= divisor;
        divisor >>= 1;
    };
    return (uint8_t)data32;
}
int main()
{
    uBit.init();
    uint8_t buf[3] = {0};
    uBit.i2c.readRegister(0x80, 0xE3, buf, 3);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];

    unsigned int data16 = ((unsigned int)msb << 8) |
                          (unsigned int)(lsb & 0xFC);
    int temp = -4685 + ((17572 * data16) >> 16);
    uBit.serial.printf("\n\rmsb %d \n\rlsb %d \n\rchecksum %d \n\r",
                       msb, lsb, check);
    uBit.serial.printf("Temperature %d.%d C \n\r",
                       temp / 100, temp % 100);
    uBit.serial.printf("crc %d \n ", crcCheck(msb, lsb, check));

    uBit.i2c.readRegister(0x80, 0xE5, buf, 3);
    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    uBit.serial.printf("\n\rmsb %d \n\rlsb %d \n\rchecksum %d \n\r",
                       msb, lsb, check);
    data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    int hum = -600 + ((12500 * data16) >> 16);
    uBit.serial.printf("Humidity %d.%d %% \n\r",
                       hum / 100, hum % 100);
    uBit.serial.printf("crc %d \n ", crcCheck(msb, lsb, check));

    return 0;
}

Page 128

#include "MicroBit.h"
MicroBit uBit;
MicroBitPin P0 = uBit.io.P0;

int main()
{
    int n = 1200;
    //n = 4400; // Uncomment for V2
    volatile int i;
    uBit.init();
    P0.setDigitalValue(1);
    P0.setDigitalValue(0);
    for (i = 0; i < n; i++)
    {
    };
    P0.setDigitalValue(1);
    int b = P0.getDigitalValue();
}

Page 134

#include "MicroBit.h"
#include <cstdio>

MicroBit uBit;
MicroBitPin P0 = uBit.io.P0;

uint32_t getByte(int b, int buf[])
{
    int i;
    uint32_t result = 0;
    b = (b - 1) * 8 + 1;
    for (i = b; i <= b + 7; i++)
    {
        result = result << 1;
        result = result | buf[i];
    }
    return result;
}

int main()
{
    int n = 800;
    int threshold = 11;
    threshold = 40; // uncomment for V2

    volatile int i;
    uBit.init();
    P0.setDigitalValue(1);
    for (;;)
    {
        P0.setDigitalValue(0);
        uBit.sleep(1);
        P0.getDigitalValue();
        for (i = 1; i < n; i++)
        {
            if (P0.getDigitalValue() == 0)
                break;
        };
        int buf[41];
        int j;
        __disable_irq();
        for (j = 0; j < 41; j++)
        {
            for (i = 1; i < n; i++)
            {
                if (P0.getDigitalValue() == 1)
                    break;
            };
            for (i = 1; i < n; i++)
            {
                if (P0.getDigitalValue() == 0)
                    break;
            }
            buf[j] = 0;
            if (i > threshold)
                buf[j] = 1;
        }
        __enable_irq();

        uint32_t byte1 = getByte(1, buf);
        uint32_t byte2 = getByte(2, buf);
        uint32_t byte3 = getByte(3, buf);
        uint32_t byte4 = getByte(4, buf);
        uint32_t byte5 = getByte(5, buf);

        int16_t humidity = (byte1 << 8) | byte2;
        int16_t temperature = (byte3 << 8) | byte4;
        if (temperature & 0x8000)
            temperature = -(temperature & 0x7FFF);

        uBit.serial.printf("Checksum %X %X \n\r", byte5,
                           (byte1 + byte2 + byte3 + byte4) & 0xFF);
        uBit.serial.printf("Humidity %d.%d%%\n\r",
                           humidity / 10, abs(humidity % 10));
        uBit.serial.printf("Temperature %d.%dC\n\r",
                           temperature / 10, abs(temperature % 10));
        char buff[10];
        sprintf(buff, "%d.%d%%", humidity / 10, abs(humidity % 10));
        uBit.display.scroll(buff, 200);
        sprintf(buff, "%hd.%dC", temperature / 10,
                abs(temperature % 10));
        uBit.display.scroll(buff, 200);
        uBit.sleep(2500);
    }
}

Page 150

#include "MicroBit.h"
#include <cstdio>

MicroBit uBit;
MicroBitPin P0 = uBit.io.P0;
MicroBitPin P1 = uBit.io.P1;

int init()
{
    int reset = 700;
    //reset = 2250; // uncomment V2
    int gap = 60;
    //gap = 200; // uncomment V2
    volatile int i;

    P0.setDigitalValue(1);
    P0.setPull(Pull - up);
    // P0.setPull(PullMode::Up); //V2

    P1.getDigitalValue();
    P0.setDigitalValue(0);
    __disable_irq();
    for (i = 0; i < reset; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 0; i < gap; i++)
    {
    };
    int b = P1.getDigitalValue();
    for (i = 0; i < reset - gap; i++)
    {
    };
    __enable_irq();
    return b;
}

void sendZero()
{
    int zero = 75;
    //zero = 240; // uncomment for V2
    int slot = 30;
    //slot = 300;// uncomment for V2
    volatile int i;
    P0.setDigitalValue(0);
    for (i = 1; i < zero; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < slot - zero; i++)
    {
    };
}

void sendOne()
{
    int one = 1;
    //one = 8; // uncomment for V2
    int slot = 30;
    //slot = 300; // uncomment for V2
    volatile int i;
    P0.setDigitalValue(0);
    for (i = 1; i < one; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < slot - one; i++)
    {
    };
}

int readBit()
{
    volatile int i;
    int sample = 20;
    //sample = 55; // uncomment for V2
    int pulse = 1;
    //pulse = 8; // uncomment for V2
    int slot = 30;
    //slot = 300; // uncomment for V2
    __disable_irq();
    P0.setDigitalValue(0);
    for (i = 1; i < pulse; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < sample; i++)
    {
    };
    int b = P1.getDigitalValue();
    __enable_irq();
    for (i = 1; i < slot - sample - pulse; i++)
    {
    };
    return b;
}

void writeBit(int b)
{
    int zero = 75;
    //zero = 240; // uncomment for V2
    int one = 1;
    //one = 8; // uncomment for V2
    int slot = 30;
    //slot = 300; // uncomment for V2
    volatile int i;
    int delay1, delay2;
    if (b == 1)
    {
        delay1 = one;
    }
    else
    {
        delay1 = zero;
    }
    delay2 = slot - delay1;
    __disable_irq();
    P0.setDigitalValue(0);
    for (i = 1; i < delay1; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < delay2; i++)
    {
    };
    __enable_irq();
}

void writeByte(int byte)
{
    int i;
    for (i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(1);
        }
        else
        {
            writeBit(0);
        }
        byte = byte >> 1;
    }
}
int readByte()
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit() << i;
    };
    return byte;
}
void convert()
{
    writeByte(0x44);
    uBit.sleep(900);
}
int main()
{
    uBit.init();

    if (init() == 1)
    {
        uBit.serial.printf("No device \n\r");
    }
    else
    {
        uBit.serial.printf("Device detected \n\r");
    }

    while (1)
    {
        init();
        writeByte(0xCC);
        convert();
        init();
        writeByte(0xCC);
        writeByte(0xBE);
        int b1 = readByte();
        int b2 = readByte();
        uBit.serial.printf("bytes %X,%X\n\r", b1, b2);
        int16_t temp = (b2 << 8 | b1);
        temp = temp * 100 / 16;
        uBit.serial.printf("Temperature %d.%d\n\r",
                           temp / 100, abs(temp % 100));
        char buff[10];
        sprintf(buff, "%d.%d", temp / 100, abs(temp % 100));
        uBit.display.scroll(buff, 200);
        uBit.sleep(2000);
    }
}

Page 154

int readBit()
{
    volatile int i;
    int sample = 20;
    sample = 55; // uncomment for V2
    int pulse = 1;
    pulse = 8; // uncomment for V2
    int slot = 30;
    slot = 300; // uncomment for V2
    __disable_irq();
    P0.setDigitalValue(0);
    for (i = 1; i < pulse; i++)
    {
    };
    P0.setDigitalValue(1);
    for (i = 1; i < sample; i++)
    {
    };

    *pinDir = 0x0;
    unsigned int b = (*inp) & mask;
    b = b >> GPIO;
    *pinDir = 0x1;
    __enable_irq();
    for (i = 1; i < slot - sample - pulse; i++)
    {
    };
    return b;
}

Page 162

int SPItransfer(uint8_t *txBuffer, uint32_t txSize,
                uint8_t *rxBuffer, uint32_t rxSize)
{
    CS.setDigitalValue(0);
    uint32_t i;
    for (i = 0; i < txSize; i++)
    {
        if (i < rxSize)
        {
            rxBuffer[i] = spi.write(txBuffer[i]);
        }
        else
        {
            spi.write(txBuffer[i]);
        }
    }
    CS.setDigitalValue(1);
    return 0;
}

Page 164

#include "MicroBit.h"

MicroBit uBit;
SPI spi(MOSI, MISO, SCK);

MicroBitPin CS(MICROBIT_ID_IO_P16, MICROBIT_PIN_P16,
               PIN_CAPABILITY_DIGITAL);
//Used by V1 only
int SPItransfer(uint8_t *txBuffer, uint32_t txSize, uint8_t *rxBuffer, uint32_t rxSize)
{
    CS.setDigitalValue(0);
    uint32_t i;
    for (i = 0; i < txSize; i++)
    {
        if (i < rxSize)
        {
            rxBuffer[i] = spi.write(txBuffer[i]);
        }
        else
        {
            spi.write(txBuffer[i]);
        }
    }
    CS.setDigitalValue(1);
    return 0;
}
int main()
{
    CS.setDigitalValue(1);
    spi.format(8, 0);
    spi.frequency(1000000);
    uint8_t buf[1] = {0xAA};
    while (1)
    {
        CS.setDigitalValue(0);
        SPItransfer(buf, 1, buf, 1); //comment out for V2
                                     // spi.transfer(buf, 1, buf, 1); //uncomment for V1

        CS.setDigitalValue(1);

        uBit.serial.printf("data %X\n\r", buf[0]);
        if (buf[0] == 0xAA)
            uBit.serial.printf("data received correctly\n\r");
    };
    release_fiber();
    return 0;
}

Page 174

#include "MicroBit.h"
MicroBit uBit;

SPI spi(MOSI, MISO, SCK);

MicroBitPin CS(MICROBIT_ID_IO_P16, MICROBIT_PIN_P16,
               PIN_CAPABILITY_DIGITAL);
//SPItransfer function is only needed for V1
int SPItransfer(uint8_t *txBuffer, uint32_t txSize,
                uint8_t *rxBuffer, uint32_t rxSize)
{
    CS.setDigitalValue(0);
    uint32_t i;
    for (i = 0; i < txSize; i++)
    {
        if (i < rxSize)
        {
            rxBuffer[i] = spi.write(txBuffer[i]);
        }
        else
        {
            spi.write(txBuffer[i]);
        }
    }
    CS.setDigitalValue(1);
    return 0;
}

int main()
{
    CS.setDigitalValue(1);
    spi.format(8, 0);
    spi.frequency(1000000);

    uint8_t buf[] = {0x01, 0x80, 0x00};
    uint8_t readBuf[3];
    CS.setDigitalValue(0);
    SPItransfer(buf, 3, readBuf, 3); // comment out for V2
    //spi.transfer(buf, 3, readBuf, 3); //uncomment for V2
    //uBit.sleep(1);//uncomment for V2
    CS.setDigitalValue(1);
    int data = ((int)readBuf[1] & 0x03) << 8 | (int)readBuf[2];
    int volts = data * 330 / 1023;
    uBit.serial.printf("data %d\n\r", volts);

    release_fiber();
    return 0;
}

Page 175

int readADC(uint8_t chan)
{
    uint8_t buf[] = {0x01, (0x08 | chan) << 4, 0x00};
    uint8_t readBuf[3];
    CS.setDigitalValue(0);
    SPItransfer(buf, 3, readBuf, 3); //Comment out for V2

    //spi.transfer(buf, 3, readBuf, 3); //uncomment for V2
    //uBit.sleep(1);//uncomment for V2
    CS.setDigitalValue(1);
    return (readBuf[1] & 0x03) << 8 | readBuf[2];
}

Page 177

volatile unsigned int *outset = (unsigned int *)(0x50000000UL + 0x508);
volatile unsigned int *outclr = (unsigned int *)(0x50000000UL + 0x50C);
unsigned int mask = 1 << 16;

void transferBytes(int *buf, int *readBuf, int len)
{
    *outclr = mask;
    readBuf[0] = spi.write(buf[0]);
    readBuf[1] = spi.write(buf[1]);
    readBuf[2] = spi.write(buf[2]);
    *outset = mask;
}

Page 182

#include "MicroBit.h"
//#define baud setBaudrate // Uncomment for V2
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.serial.baud(115200);
    uBit.serial.send("A\r\n");
}

Page 182

#include "MicroBit.h"
/* Uncomment for V2
#define baud setBaudrate
#define USBTX MICROBIT_PIN_UART_TX
#define USBRX MICROBIT_PIN_UART_RX
*/
MicroBitSerial serial(USBTX, USBRX);

int main()
{
    serial.baud(115200);
    serial.send("A\r\n");
    release_fiber();
}

Page 189

#include "MicroBit.h"
//#define baud setBaudrate //uncomment for V2

void onChar(MicroBitEvent e)
{
    ManagedString s = uBit.serial.read(1);
    uBit.serial.clearRxBuffer();
    uBit.display.scroll(s);
    uBit.serial.eventAfter(1);
};

MicroBit uBit;

int main()
{
    uBit.init();
    uBit.serial.(20);
    uBit.messageBus.listen(MICROBIT_ID_SERIAL,
                           MICROBIT_SERIAL_EVT_HEAD_MATCH, onChar);
    uBit.serial.eventAfter(1);
    while (1)
        uBit.sleep(1000);
    release_fiber();
}

Page 198

#include "MicroBit.h"

MicroBit uBit;

void initWiFi();
int ATWiFi();
int find(ManagedString c, ManagedString s);
void debug(ManagedString s);
//Comment out for V2
#define Tx MICROBIT_PIN_P0
#define Rx MICROBIT_PIN_P1
//

/* Uncomment For V2
#define baud setBaudrate
#define USBTX uBit.io.usbTx
#define USBRX uBit.io.usbRx
#define Tx  uBit.io.P0
#define Rx  uBit.io.P1
*/
#define DEBUG 1

int main()
{
    initWiFi();
    ATWiFi();
    while (1)
        uBit.sleep(1000);
    release_fiber();
}
void initWiFi()
{
    uBit.serial.redirect(Tx, Rx);
    uBit.serial.baud(115200);
    uBit.serial.setRxBufferSize((uint8_t) + 500);
}

int ATWiFi()
{
    uBit.serial.send("AT\r\n", SYNC_SPINWAIT);
    uBit.sleep(150);
    ManagedString s = uBit.serial.read(500, ASYNC);
    if (DEBUG)
        debug("\n\rAT \n\r" + s + "\n\r");
    return find("OK", s);
}

void debug(ManagedString s)
{
    uBit.serial.redirect(USBTX, USBRX);
    uBit.serial.send(s, SYNC_SPINWAIT);
    uBit.serial.redirect(Tx, Rx);
}

int find(ManagedString c, ManagedString s)
{
    int i;

    for (i = 0; i < (s.length() - c.length()); i++)
    {
        if (c == s.substring(i, c.length()))
            break;
    }

    if (i == (s.length() - c.length()))
        return 0;
    return 1;
}

Page 211

#include "MicroBit.h"

MicroBit uBit;

void initWiFi();
int ATWiFi();
int find(ManagedString c, ManagedString s);
void debug(ManagedString s);
//Comment out for V2
#define Tx MICROBIT_PIN_P0
#define Rx MICROBIT_PIN_P1
//
/*  Uncomment for V2
#define baud setBaudrate
#define USBTX uBit.io.usbTx
#define USBRX uBit.io.usbRx
#define Tx uBit.io.P0
#define Rx uBit.io.P1
*/
#define DEBUG 1
#include "MicroBit.h"

void initWiFi();
int ATWiFi();
int resetWiFi();
int setUARTWiFi();
int scanWiFi();
int getIPWiFi();
int modeWiFi(int mode);
int connectWiFi(ManagedString ssid, ManagedString pass);
int getWebPageWiFi(ManagedString URL, ManagedString page);
int getVersionWiFi();
int startServerWiFi();

int waitForWiFi(ManagedString target, int retry, int pause);
int find(ManagedString c, ManagedString s);
void debug(ManagedString s);

int main()
{
    uBit.init();
    initWiFi();
    modeWiFi(1);
    connectWiFi("ssid", "password");
    getIPWiFi();
    startServerWiFi();
    release_fiber();
}

void initWiFi()
{
    uBit.serial.redirect(Tx, Rx);
    uBit.serial.baud(115200);
    uBit.serial.setRxBufferSize((uint8_t) + 500);
}

int ATWiFi()
{
    uBit.serial.send("AT\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 150, 10);
}

int getVersionWiFi()
{
    uBit.serial.send("AT+GMR\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int resetWiFi()
{
    uBit.serial.send("AT+RST\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 1000, 10);
}

int setUARTWiFi()
{
    uBit.serial.send("AT+UART_CUR=115200,8,1,0,0\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int scanWiFi()
{
    uBit.serial.send("AT+CWLAP\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 500, 50);
}

int modeWiFi(int mode)
{
    ManagedString cmd = "AT+CWMODE_CUR=" + ManagedString(mode) + "\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int connectWiFi(ManagedString ssid, ManagedString pass)
{
    ManagedString cmd = "AT+CWJAP_CUR=\"" + ssid + "\",\"" + pass + "\"\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 20);
}

int getIPWiFi()
{
    uBit.serial.send("AT+CIFSR\r\n", SYNC_SPINWAIT);
    return waitForWiFi("OK", 200, 10);
}

int getWebPageWiFi(ManagedString URL, ManagedString page)
{
    ManagedString cmd = "AT+CIPSTART=\"TCP\",\"" + URL + "\",80\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    if (waitForWiFi("OK", 100, 20) == 0)
        return 0;

    ManagedString http = "GET " + page + "HTTP/1.0\r\nHost:" + URL + "\r\n\r\n";
    cmd = "AT+CIPSEND=" + ManagedString(http.length()) + "\r\n";
    uBit.serial.send(cmd, SYNC_SPINWAIT);
    int retry;
    ManagedString s;
    s = "";
    retry = 40;
    do
    {
        uBit.sleep(100);
        s = s + uBit.serial.read(500, ASYNC);
        retry--;
    } while (find(">", s) == 0 && retry != 0);

    uBit.serial.send(http, SYNC_SPINWAIT);
    retry = 100;
    do
    {
        uBit.sleep(100);
        s = s + uBit.serial.read(500, ASYNC);
        retry--;
    } while (s.length() < 500 && retry != 0);

    if (DEBUG)
        debug("\n\rPage\n\r" + s + "\n\r");
    return 1;
}

int startServerWiFi()
{
    uBit.serial.send("AT+CIPMUX=1\r\n", SYNC_SPINWAIT);
    if (waitForWiFi("OK", 100, 20) == 0)
        return 0;

    uBit.serial.send("AT+CIPSERVER=1,80\r\n", SYNC_SPINWAIT);
    if (waitForWiFi("OK", 100, 20) == 0)
        return 0;

    ManagedString s;

    for (;;)
    {
        s = "";
        do
        {
            uBit.sleep(100);
            if (s > 500)
                s = "";
            s = uBit.serial.read(500, ASYNC);
        } while (find("+IPD", s) == 0);
        if (DEBUG)
            debug("\n\rClient Connected\n\r" + s + "\n\r");

        int b = find("+IPD", s);
        s = s.substring(b + 1, s.length());
        b = find(",", s);
        s = s.substring(b + 1, s.length());
        b = find(",", s);
        ManagedString id = s.substring(0, b);
        if (DEBUG)
            debug("\n\rTCP id:" + id + "\n\r");

        ManagedString headers = "HTTP/1.0 200 OK\r\n";
        headers = headers + "Server: micro:bit\r\n";
        headers = headers + "Content-type: text/html\r\n\r\n";

        ManagedString html =
            "<html><head><title>Temperature</title></"
            "head><body>{\"humidity\":81%,\"airtemperature\":23.5C}</p></body></html>\r\n";
        ManagedString data = headers + html;

        ManagedString cmd = "AT+CIPSEND=" + id + "," + ManagedString(data.length()) + "\r\n";
        uBit.serial.send(cmd, SYNC_SPINWAIT);
        s = "";
        int retry = 40;
        do
        {
            uBit.sleep(100);
            s = s + uBit.serial.read(500, ASYNC);
            retry--;
        } while (find(">", s) == 0 && retry != 0);

        uBit.serial.send(data, SYNC_SPINWAIT);

        if (waitForWiFi("OK", 100, 100) == 0)
            return 0;
        if (DEBUG)
            debug("\n\rData Sent\n\r");

        cmd = "AT+CIPCLOSE=" + id + "\r\n";
        uBit.serial.send(cmd, SYNC_SPINWAIT);
        if (waitForWiFi("OK", 100, 100) == 0)
            return 0;
    }
}

void debug(ManagedString s)
{
    uBit.serial.redirect(USBTX, USBRX);
    uBit.serial.send(s, SYNC_SPINWAIT);
    uBit.serial.redirect(Tx, Rx);
}

int find(ManagedString c, ManagedString s)
{
    int i;

    for (i = 0; i < (s.length() - c.length()); i++)
    {
        if (c == s.substring(i, c.length()))
            break;
    }

    if (i == (s.length() - c.length()))
        return 0;
    return i;
}

int waitForWiFi(ManagedString target, int retry, int pause)
{
    ManagedString s;
    do
    {
        uBit.sleep(pause);
        if (s.length() > 500)
            s = "";
        s = s + uBit.serial.read(500, ASYNC);
        retry--;
    } while (find(target, s) == 0 && retry != 0);
    if (DEBUG)
        debug("\n\r" + s + "\n\r");
    return retry;
}

Page 222

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.disable();

    DigitalOut col3(P0_6, 0);
    DigitalOut row2(P0_14);
    while (1)
    {
        row2 = 1;
        wait(0.2);
        row2 = 0;
        wait(0.2);
    }

    release_fiber();
    return 0;
}

Page 224

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.disable();
    uBit.io.row3.setDigitalValue(1);

    while (1)
    {
        uBit.io.col3.setDigitalValue(1);
        uBit.sleep(100);
        uBit.io.col3.setDigitalValue(0);
        uBit.sleep(100);
    }

    release_fiber();
    return 0;
}

Page 224

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.display.disable();

    while (1)
    {

        uBit.io.col1.setDigitalValue(0);
        uBit.io.row1.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col1.setDigitalValue(1);
        uBit.io.row1.setDigitalValue(0);
        uBit.io.col2.setDigitalValue(0);
        uBit.io.row2.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col2.setDigitalValue(1);
        uBit.io.row2.setDigitalValue(0);
        uBit.io.col3.setDigitalValue(0);
        uBit.io.row3.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col3.setDigitalValue(1);
        uBit.io.row3.setDigitalValue(0);
        uBit.io.col4.setDigitalValue(0);
        uBit.io.row4.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col4.setDigitalValue(1);
        uBit.io.row4.setDigitalValue(0);
        uBit.io.col5.setDigitalValue(0);
        uBit.io.row5.setDigitalValue(1);
        uBit.sleep(500);
        uBit.io.col5.setDigitalValue(1);
        uBit.io.row5.setDigitalValue(0);
    }

    release_fiber();
    return 0;
}

Page 228

#include "MicroBit.h"

MicroBit uBit;
int clickCount = 0;

void startGame();
int playGame();
void endGame(int position);
void countDown();
void drawPlayArea();
void flashMan(int x, int y, int p, int vx, int vy);
void setUpButton();
void moveHorizontal();
void moveVertical(int x, int h);
void buttonClickCount(MicroBitEvent e);

int main()
{
    uBit.init();
    startGame();
    int position = playGame();
    endGame(position);
    release_fiber();
    return 0;
}

void startGame()
{
    countDown();
    uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE);
    drawPlayArea();
    setUpButton();
}

void countDown()
{
    int t;
    for (t = 5; t >= 0; t--)
    {
        uBit.display.scroll(t);
    }
    uBit.display.scroll("!");
}

void drawPlayArea()
{
    uBit.display.clear();
    int y;
    for (y = 1; y <= 5; y++)
    {
        uBit.display.image.setPixelValue(2, y, 255);
    }
}

int playGame()
{
    int position = 4;
    clickCount = 0;
    int t1 = uBit.systemTime();

    while (uBit.systemTime() - t1 < 20000)
    {
        flashMan(4, position, clickCount, 0, -1);
        if (clickCount > 10)
        {
            position = position - 1;
            clickCount = 0;
            if (position == 0)
                break;
        }
    }
    return position;
}

void endGame(int position)
{
    if (position == 0)
    {
        moveHorizontal();
        moveVertical(0, 0);
    }
    else
    {
        moveVertical(4, position);
    }
}

void setUpButton()
{
    uBit.buttonB.setEventConfiguration(MICROBIT_BUTTON_ALL_EVENTS);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_B,
                           MICROBIT_BUTTON_EVT_CLICK,
                           buttonClickCount);
}

void buttonClickCount(MicroBitEvent e)
{
    clickCount++;
}

void flashMan(int x, int y, int p, int vx, int vy)
{
    uBit.display.image.setPixelValue(x, y, 0);
    uBit.display.image.setPixelValue(x + vx, y + vy, 0);
    uBit.sleep(100);
    uBit.display.image.setPixelValue(x, y, 25 * (10 - p));
    uBit.display.image.setPixelValue(x + vx, y + vy, 25 * p);
    uBit.sleep(100);
}

void moveHorizontal()
{
    int x, fraction;
    for (x = 4; x >= 0; x--)
    {
        for (fraction = 0; fraction <= 10; fraction++)
        {
            flashMan(x, 0, fraction, -1, 0);
        }
    }
}

void moveVertical(int x, int h)
{
    int y, fraction;
    if (h != 0)
        uBit.display.image.setPixelValue(x, h - 1, 0);
    for (y = h; y <= 4; y++)
    {
        for (fraction = 0;
             fraction <= 10; fraction++)
        {
            flashMan(x, y, fraction, 0, 1);
        }
    }
}

Page 238

void onData(MicroBitEvent e)
{
    uBit.display.print("Click");
    return;
}

int main()
{
    uBit.init();
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A,
                           MICROBIT_BUTTON_EVT_CLICK, onData);
    uBit.radio.enable();
    while (1)
    {
        uBit.sleep(1000);
    }
}

Page 239

#include "MicroBit.h"
MicroBit uBit;
int main()
{
    uBit.init();
    uBit.radio.enable();
    uBit.display.print("TX");
    while (1)
    {
        if (uBit.buttonA.isPressed())
        {
            uBit.display.print("1");
            uBit.radio.datagram.send("1");
        }

        uBit.sleep(100);
        uBit.display.clear();
    }
    return 0;
}

Page 239

#include "MicroBit.h"
MicroBit uBit;

void onData(MicroBitEvent e)
{
    ManagedString s = uBit.radio.datagram.recv();
    uBit.display.print(s);
}

int main()
{
    uBit.init();

    uBit.messageBus.listen(MICROBIT_ID_RADIO,
                           MICROBIT_RADIO_EVT_DATAGRAM, onData);
    uBit.radio.enable();
    uBit.display.print("RX");
    while (1)
    {
        uBit.sleep(100);
        uBit.display.clear();
    }
}

Page 243

#include "MicroBit.h"
MicroBit uBit;
ManagedString setSound(ManagedString audio,
                       ManagedString data, int s)
{
    return audio.substring(0, s) + data +
           audio.substring(s + data.length(),
                           audio.length() - s - data.length());
}

int main()
{
    uBit.init();
    // 72 characters
    static ManagedString soundData(
       "000000000000000000000000000000000000
                     000000000000000000000000000000000000");

    soundData = setSound(soundData, "0", 0);     // Wave
    soundData = setSound(soundData, "1023", 1);  // volume start
    soundData = setSound(soundData, "1023", 26); // volume end
    soundData = setSound(soundData, "1000", 5);  // frequency start
    soundData = setSound(soundData, "1000", 18); // frequency end
    soundData = setSound(soundData, "00", 13);   // shape
    
    soundData = setSound(soundData, "500", 9);   // duration
    soundData = setSound(soundData, "0128", 30); // steps

    uBit.audio.soundExpressions.play(soundData);

    return 0;
}

Page 245

#include "MicroBit.h"

MicroBit uBit;

void beepOn(MicroBitEvent e)
{
    uBit.io.P0.setAnalogValue(512);
    uBit.io.P0.setAnalogPeriodUs(1000000 / 500);
    uBit.display.image.setPixelValue(2, 2, 255);
}

void beepOff(MicroBitEvent e)
{
    uBit.io.P0.setAnalogValue(0);
    uBit.display.image.setPixelValue(2, 2, 0);
}

int main()
{
    uBit.init();
    uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE);
    uBit.radio.enable();

    uBit.radio.event.listen(MICROBIT_ID_BUTTON_A,
                            MICROBIT_BUTTON_EVT_DOWN);
    uBit.radio.event.listen(MICROBIT_ID_BUTTON_A,
                            MICROBIT_BUTTON_EVT_UP);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A,
                           MICROBIT_BUTTON_EVT_DOWN, beepOn);
    uBit.messageBus.listen(MICROBIT_ID_BUTTON_A,
                           MICROBIT_BUTTON_EVT_UP, beepOff);
    while (1)
    {
        uBit.sleep(100);
    }
}

 

Program Listings

 

Programming the Raspberry
Pi Pico/W in C
Second Edtion

picoC2E360

 

We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.

The best solution is to provide the source code of the programs in a form that can be copied and pasted into a NetBeans or VS Code project. 

The only downside is that you have to create a project to paste the code into.

To do this follow the instructions in the book.

All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book. This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.

If anything you consider important is missing or if you have any requests or comments  contact:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 27

#include "pico/stdlib.h"

int main() {
    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);
    while (true) {
        gpio_put(25, 1);
        sleep_ms(500);
        gpio_put(25, 0);
        sleep_ms(500);
    }
}
  

Page 28

cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(blinky C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(blinky
 blinky.c
)
target_link_libraries(blinky pico_stdlib)
pico_add_extra_outputs(blinky)

Page 29

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

int main() {
    stdio_init_all();
    cyw43_arch_init();
    while (true) {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(500);
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(500);
    }
}

Page 30

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(blinky C CXX ASM)

pico_sdk_init()
add_executable(blinky
blinky.c
)
target_include_directories(blinky PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(blinky pico_cyw43_arch_none pico_stdlib)
pico_add_extra_outputs(blinky)

Page 36

{
    "version": "0.2.0",
    "configurations": [
      {
        "name": "Cortex Debug",
        "cwd": "${workspaceRoot}",
        "executable": "${command:cmake.launchTargetPath}",
        "request": "launch",
        "type": "cortex-debug",
        "servertype": "openocd",
        "gdbPath": "gdb-multiarch",
        "device": "RP2040",
        "configFiles": [
          "interface/raspberrypi-swd.cfg",
          "target/rp2040.cfg"
          ],
        "svdFile":  
         "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
         "runToEntryPoint":"main",
        // Give restart the same functionality as runToMain
        "postRestartCommands": [
            "break main",
            "continue"
        ]
      }
    ]
  }

Page 40

{
    "version": "0.2.0",
    "configurations": [    
    {
       "name": "Pico Debug",
       "cwd": "${workspaceRoot}",
       "executable": "${command:cmake.launchTargetPath}",
       "request": "launch",
       "type": "cortex-debug",
       "servertype": "openocd",  
       "gdbPath": "arm-none-eabi-gdb",
       "device": "RP2040",
       "configFiles": [
       "interface/picoprobe.cfg",
       "target/rp2040.cfg"
        ],
       "svdFile":"${env:PICO_SDK_PATH}/src/rp2040/
                                    hardware_regs/rp2040.svd",
       "runToEntryPoint":"main",
 // Work around for stopping at main on restart
       "postRestartCommands": [
       "break main",
       "continue"
       ]
    }
  ]
}
 
  
 

Page 49

C File  blinky2.c

#include "pico/stdlib.h"
int main()
{
    gpio_init(22);
    gpio_set_dir(22, true);
    while (true)
    {
        gpio_put(22, 1);
        sleep_ms(1000);
        gpio_put(22, 0);
        sleep_ms(1000);
    }
}
 
CMAKE File
 
cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)

project(NewBlinky C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(blink
 blinky2.c
)
target_link_libraries(blink pico_stdlib)
pico_add_extra_outputs(blink)
 

Page 56

#include "pico/stdlib.h"
int main()
{
 gpio_set_function(22, GPIO_FUNC_SIO);
 gpio_set_dir(22, true);
 while (true)
 {
  gpio_put(22, 1);
  gpio_put(22, 0);
 }
}
 

Page 59

#include "pico/stdlib.h"
int main()
{
 gpio_set_function(22, GPIO_FUNC_SIO);
 gpio_set_dir(22, true);
 while (true)
    {
        sleep_us(1);
        gpio_put(22, 0);      
        sleep_us(1);
        gpio_put(22, 1);
    }
}
 

Page 60

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    volatile int i;
    int n = 1;
    while (true)
    {
        for (i = 0; i < n; i++){};
        gpio_put(22, 0);
        for (i = 0; i < n; i++){};
        gpio_put(22, 1);
    }
}
 

Page 62

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, true);
    while (true)
    {
        gpio_put(22, 0);
        gpio_put(21, 1);
        gpio_put(22, 1);
        gpio_put(21, 0);
    }
}
 

Page 63

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, true);

    uint32_t mask = (1 << 22) | (1 << 21);
    uint32_t value1 = 1 << 21;
    uint32_t value2 = 1 << 22;
    while (true)
    {
        gpio_put_masked(mask, value1);
        gpio_put_masked(mask, value2);
    }
}
  

Page 85

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_up(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);

    while (true)
    {
        if (gpio_get(21))
        {
            gpio_put(22, 0);
        }
        else
        {
            gpio_put(22, 1);
        }
    }
}

Page 86

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_down(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_put(22, 0);
    while (true)
    {
        while (gpio_get(21) == 0)
        {
        };
        while (gpio_get(21) == 1)
        {
        };
        gpio_put(22, 1);
        sleep_ms(1000);
        gpio_put(22, 0);
    }
}

Page 87

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_down(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_put(22, 0);

    uint64_t t;

    while (true)
    {
        while (gpio_get(21) == 0)
        {
        };
        t = time_us_64();
        sleep_ms(1);
        while (gpio_get(21) == 1)
        {
        };
        t = (uint64_t)(time_us_64() - t);
        if (t < 2000 * 1000)
        {
            gpio_put(22, 1);
            sleep_ms(1000);
            gpio_put(22, 0);
        }
        else
        {
            for (int i = 0; i < 10; i++)
            {
                gpio_put(22, 1);
                sleep_ms(100);
                gpio_put(22, 0);
                sleep_ms(100);
            }
        }
    }
}
 
 

Page 89

 
#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
 stdio_init_all();

 while (true) {
  printf("Hello Serial World\n");
  stdio_flush ();
  sleep_ms(1000);        
 }
}
#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;

    while (true)
    {
        while (gpio_get(22) == 1)
        {
        };
        while (gpio_get(22) == 0)
        {
        };
        t = time_us_64();
        while (gpio_get(22) == 1)
        {
        };
        t = (uint64_t)(time_us_64() - t);
        printf("%llu\n", t);
        sleep_ms(1000);
    }
}
 
Page 92
#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;
    int s = 0;
    int i;
    int count = 0;
    while (true)
    {
        i = gpio_get(22);
        t = time_us_64() + 100;
        switch (s)
        {
        case 0: //button not pushed
            if (i)
            {
                s = 1;
                count++;
                printf("Button Push %d \n\r", count);
            }
            break;
        case 1: //Button pushed
            if (!i)
            {
                s = 0;
            }
            break;
        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t});
    }
}

Page 94

#include <stdio.h>
#include "pico/stdlib.h"
int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;
    uint64_t tpush, twait;
    int s = 0, i;
    int count = 0;
    while (true)
    {
        i = gpio_get(22);
        t = time_us_64();
        switch (s)
        {
        case 0: //button not pushed
            if (i)
            {
                s = 1;
                tpush = t;
            }
            break;
        case 1: //Button pushed
            if (!i)
            {
                s = 0;
                if ((t - tpush) > 2000000)
                {
                    printf("Button held \n\r");
                }
                else
                {
                    printf("Button pushed \n\r");
                }
                fflush(stdout);
            }
            break;
        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t + 1000});
    }
}

Page 96

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, true);
    gpio_set_function(20, GPIO_FUNC_SIO);
    gpio_set_dir(20, true);
    gpio_set_function(19, GPIO_FUNC_SIO);
    gpio_set_dir(19, true);

    gpio_put(19, 1);
    gpio_put(20, 0);
    gpio_put(21, 0);

    uint64_t t, tpush, twait;
    int s = 0;
    int buttonState = gpio_get(22);
    int edge;
    int buttonNow;

    while (true)
    {
        t = time_us_64();
        buttonNow = gpio_get(22);
        edge = buttonState - buttonNow;
        buttonState = buttonNow;
        switch (s)
        {
        case 0:
            if (edge == 1)
            {
                s = 1;
                gpio_put(19, 0);
                gpio_put(20, 1);
                gpio_put(21, 0);
            }
            break;
        case 1:
            if (edge == 1)
            {
                s = 2;
                gpio_put(19, 0);
                gpio_put(20, 0);
                gpio_put(21, 1);
            }
            break;
        case 2:
            if (edge == 1)
            {
                s = 0;
                gpio_put(19, 1);
                gpio_put(20, 0);
                gpio_put(21, 0);
            }
            break;

        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t + 1000});
    }
}

Page 102

uint32_t gpio_get_events(uint gpio)
{
    int32_t mask = 0xF << 4 * (gpio % 8);
    return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
    gpio_acknowledge_irq(gpio, events);
}

Page 103

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    printf("Press Button\n");
    sleep_ms(20000);
    if (gpio_get(22))
    {
        printf("Button Pressed\n");
    }
    else
    {
        printf("Button Not Pressed\n");
    }
}

Page 103-104

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/structs/iobank0.h"

uint32_t gpio_get_events(uint gpio)
{
    int32_t mask = 0xF << 4 * (gpio % 8);
    return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
    gpio_acknowledge_irq(gpio, events);
}

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    printf("Press Button\n");
    gpio_clear_events(22, GPIO_IRQ_EDGE_RISE);
    sleep_ms(20000);
    int32_t event = gpio_get_events(22);
    gpio_clear_events(22, GPIO_IRQ_EDGE_RISE);
    if (event & GPIO_IRQ_EDGE_RISE)
    {
        printf("Button Pressed\n");
    }
    else
    {
        printf("Button Not Pressed\n");
    }
}

Page 105

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/structs/iobank0.h"

uint32_t gpio_get_events(uint gpio)
{
    int32_t mask = 0xF << 4 * (gpio % 8);
    return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
    gpio_acknowledge_irq(gpio, events);
}

int main()
{
    uint64_t t;

    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    while (true)
    {
        gpio_clear_events(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
        while (!(gpio_get_events(22) & GPIO_IRQ_EDGE_RISE))
        {
        };
        t = time_us_64();
        gpio_clear_events(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
        while (!(gpio_get_events(22) & GPIO_IRQ_EDGE_FALL))
        {
        };
        t = (uint64_t)(time_us_64() - t);
        printf("%llu\n", t);
        sleep_ms(1000);
    }
}

Page 107

#include <stdio.h>
#include "pico/stdlib.h"

static uint64_t t;
void MyIRQHandler(uint gpio, uint32_t events)
{
    t = time_us_64() - t;
    printf("GPIO %d %X %d \n", gpio, events, t);
}

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &MyIRQHandler);
    while (1)
    {
    };
    return 0;
}

Page 110

#include <stdio.h>
#include "pico/stdlib.h"

 uint64_t t;

void MyIRQHandler(uint gpio, uint32_t events)
{
    t = time_us_64() ;
    printf("GPIO %d %X %d \n", gpio, events, t);
}

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE |
                         GPIO_IRQ_EDGE_FALL, true, &MyIRQHandler);

    while (1)
    {
        printf("doing something\n\r");
    };

    return 0;
}

Page 124   complete program - remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;

    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

int main()
{
    gpio_set_function(22, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(22);
    uint chan = pwm_gpio_to_channel(22);
    pwm_set_freq_duty(slice_num, chan, 50, 75);
    pwm_set_enabled(slice_num, true);
    return 0;
}

Page 125  complete program - remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num,uint chan,
                                         uint32_t f, int d)
{
 uint32_t clock = 125000000;
 uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
 if (divider16 / 16 == 0)
     divider16 = 16;
 uint32_t wrap = clock * 16 / divider16 / f - 1;
 pwm_set_clkdiv_int_frac(slice_num, divider16/16, divider16 & 0xF);
 pwm_set_wrap(slice_num, wrap);
 pwm_set_chan_level(slice_num, chan, wrap * d / 100);
 return wrap;
}
uint32_t pwm_get_wrap(uint slice_num){
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);
    gpio_set_function(21, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);
    uint chan20 = pwm_gpio_to_channel(20);
    uint chan21 = pwm_gpio_to_channel(21);
    uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 75);
    pwm_set_duty(slice_num, chan21, 25);

    pwm_set_enabled(slice_num, true);

    return 0;
}
 

Page 128 complete program - remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan,
                           uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);

    uint slice_num = pwm_gpio_to_slice_num(20);
    uint chan20 = pwm_gpio_to_channel(20);

    uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 50);

    pwm_set_enabled(slice_num, true);
    while (true)
    {
        pwm_set_duty(slice_num, chan20, 25);
        pwm_set_duty(slice_num, chan20, 50);
    }
    return 0;
}

Page 129 complete program - remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan,
                           uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);
    uint chan20 = pwm_gpio_to_channel(20);
    uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 50);
    pwm_set_enabled(slice_num, true);
    while (true)
    {
        pwm_set_duty(slice_num, chan20, 25);
        while (pwm_get_counter(slice_num))
        {
        };
        pwm_set_duty(slice_num, chan20, 50);
        while (pwm_get_counter(slice_num))
        {
        };
    }
    return 0;
}

Page 131 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

uint slice_num;
uint chan20;
uint state = 0;

void MyIRQHandler()
{
    pwm_clear_irq(slice_num);
    if (state)
    {
        pwm_set_duty(slice_num, chan20, 25);
    }
    else
    {
        pwm_set_duty(slice_num, chan20, 50);
    }
    state = ~state;
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);

    slice_num = pwm_gpio_to_slice_num(20);
    chan20 = pwm_gpio_to_channel(20);

    pwm_clear_irq(slice_num);
    pwm_set_irq_enabled(slice_num, true);
    irq_set_exclusive_handler(PWM_IRQ_WRAP, MyIRQHandler);
    irq_set_enabled(PWM_IRQ_WRAP, true);

    uint wrap = pwm_set_freq_duty(slice_num, chan20, 100000, 25);
    pwm_set_enabled(slice_num, true);
    while (true)
    {
    }
    return 0;
}

Page 133 - 134 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"
#include "math.h"

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
uint slice_num;
uint chan20;
uint state = 0;
uint8_t wave[256];

void MyIRQHandler()
{
    pwm_clear_irq(slice_num);
    pwm_set_duty(slice_num, chan20, wave[state]);
    state = (state + 1) % 256;
}

int main()
{

    for (int i = 0; i < 256; i++)
    {
        wave[i] = (uint8_t)((128.0 + sinf((float)i * 2.0 * 3.14159 / 256.0) * 128.0) * 100.0 / 256.0);
    }

    gpio_set_function(22, GPIO_FUNC_PWM);

    slice_num = pwm_gpio_to_slice_num(22);
    uint chan22 = pwm_gpio_to_channel(22);

    pwm_clear_irq(slice_num);
    pwm_set_irq_enabled(slice_num, true);
    irq_set_exclusive_handler(PWM_IRQ_WRAP, MyIRQHandler);
    irq_set_enabled(PWM_IRQ_WRAP, true);

    pwm_set_clkdiv_int_frac(slice_num, 1, 0);
    pwm_set_wrap(slice_num, 255);

    pwm_set_enabled(slice_num, true);
    while (true)
    {
    }
    return 0;
}

Page 135 complte program remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(22, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(22);

    uint chan22 = pwm_gpio_to_channel(22);
    pwm_set_freq_duty(slice_num, chan22, 281, 50);

    pwm_set_enabled(slice_num, true);
}

Page 136 complete program remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(25, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(25);
    uint chan = pwm_gpio_to_channel(25);
    pwm_set_freq_duty(slice_num, chan, 2000, 0);
    pwm_set_enabled(slice_num, true);

    while (true)
    {
        for (int d = 0; d <= 100; d++)
        {
            pwm_set_duty(slice_num, chan, d);
            sleep_ms(50);
        }
    }
}

Page 138  complete program remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(25, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(25);
    uint chan = pwm_gpio_to_channel(25);

    pwm_set_freq_duty(slice_num, chan, 2000, 0);

    pwm_set_enabled(slice_num, true);
    int d = 0;
    while (true)
    {
        for (int b = 0; b <= 100; b++)
        {
            d = (b * b * b) / 10000;
            pwm_set_duty(slice_num, chan, d);
            sleep_ms(50);
        }
    }
}
 
  

Page 140 remember to add hardware_pwm to the CMakeLists.txt file 

#include "pico/stdlib.h"
#include "hardware/pwm.h"

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);
    gpio_set_function(21, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);

    uint chanA = pwm_gpio_to_channel(20);
    uint chanB = pwm_gpio_to_channel(21);
    pwm_set_clkdiv_int_frac(slice_num, 2, 0);
    pwm_set_wrap(slice_num, 127);
    pwm_set_chan_level(slice_num, chanA, 63);
    pwm_set_clkdiv_mode(slice_num, PWM_DIV_B_RISING);
    pwm_set_enabled(slice_num, true);
}

Page 142 remember to add hardware_pwm to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
int main()
{
    stdio_init_all();
    gpio_set_function(20, GPIO_FUNC_PWM);
    gpio_set_function(21, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);

    uint chanA = pwm_gpio_to_channel(20);
    uint chanB = pwm_gpio_to_channel(21);

    pwm_set_clkdiv_int_frac(slice_num, 20, 0);
    int maxcount = 125000000 * 10 / 20 / 1000;

    pwm_set_wrap(slice_num, 65535);
    pwm_set_chan_level(slice_num, chanA, 100);
    pwm_set_clkdiv_mode(slice_num, PWM_DIV_B_HIGH);

    while (true)
    {
        pwm_set_enabled(slice_num, true);
        sleep_ms(10);
        pwm_set_enabled(slice_num, false);
        uint16_t count = pwm_get_counter(slice_num);
        pwm_set_counter(slice_num, 0);
        printf("count= %u  duty cycle=%d %%\n",
               count, (int)count * 100 / maxcount);
        sleep_ms(1000);
    }
}

Page 150,152,152 remember to add hardware_pwm to the CMakeLists.txt file 

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

typedef struct
{
    uint gpio;
    uint slice;
    uint chan;
    uint speed;
    uint freq;
    uint resolution;
    bool on;
} Motor;

void motorInit(Motor *m, uint gpio, uint freq)
{
    gpio_set_function(gpio, GPIO_FUNC_PWM);
    m->gpio = gpio;
    m->slice = pwm_gpio_to_slice_num(gpio);
    m->chan = pwm_gpio_to_channel(gpio);
    m->freq = freq;
    m->speed = 0;
    m->resolution = pwm_set_freq_duty(m->slice, m->chan, m->freq, m->speed);
    m->on = false;
}

void motorspeed(Motor *m, int s)
{
    pwm_set_duty(m->slice, m->chan, s);
    m->speed = s;
}
void motorOn(Motor *m)
{
    pwm_set_enabled(m->slice, true);
    m->on = true;
}

void motorOff(Motor *m)
{
    pwm_set_enabled(m->slice, false);
    m->on = false;
}

int main()
{
    Motor mot1;
    motorInit(&mot1, 21, 2000);
    motorspeed(&mot1, 50);
    motorOn(&mot1);
    return 0;
}

 

Page 156 remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

typedef struct
{
    uint gpioForward;
    uint gpioBackward;
    uint slice;
    uint Fchan;
    uint Bchan;
    bool forward;
    uint speed;
    uint freq;
    uint resolution;
    bool on;
} BiMotor;

void BiMotorInit(BiMotor *m, uint gpioForward, uint gpioBackward, uint freq)
{
    gpio_set_function(gpioForward, GPIO_FUNC_PWM);
    m->gpioForward = gpioForward;
    m->slice = pwm_gpio_to_slice_num(gpioForward);
    m->Fchan = pwm_gpio_to_channel(gpioForward);

    gpio_set_function(gpioBackward, GPIO_FUNC_PWM);
    m->gpioBackward = gpioBackward;
    m->Bchan = pwm_gpio_to_channel(gpioBackward);

    m->freq = freq;
    m->speed = 0;
    m->forward = true;
    m->resolution = pwm_set_freq_duty(m->slice, m->Fchan, m->freq, 0);
    pwm_set_duty(m->slice, m->Bchan, 0);
    m->on = false;
}

void BiMotorspeed(BiMotor *m, int s, bool forward)
{
    if (forward)
    {
        pwm_set_duty(m->slice, m->Bchan, 0);
        pwm_set_duty(m->slice, m->Fchan, s);
        m->forward = true;
    }
    else
    {
        pwm_set_duty(m->slice, m->Fchan, 0);
        pwm_set_duty(m->slice, m->Bchan, s);
        m->forward = true;
    }
    m->speed = s;
}

void BiMotorOn(BiMotor *m)
{
    pwm_set_enabled(m->slice, true);
    m->on = true;
}

void BiMotorOff(BiMotor *m)
{
    pwm_set_enabled(m->slice, false);
    m->on = false;
}

int main()
{
    BiMotor mot1;
    BiMotorInit(&mot1, 20, 21, 2000);

    BiMotorOn(&mot1);
    while (true)
    {
        BiMotorspeed(&mot1, 50, true);
        sleep_ms(2000);
        BiMotorspeed(&mot1, 25, false);
        sleep_ms(2000);
    }

    return 0;
}

Page 162, 163, 164 remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

void pwm_set_dutyH(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 10000);
}

typedef struct
{
    uint gpio;
    uint slice;
    uint chan;
    uint speed;
    uint resolution;
    bool on;
    bool invert;
} Servo;

void ServoInit(Servo *s, uint gpio, bool invert)
{
    gpio_set_function(gpio, GPIO_FUNC_PWM);
    s->gpio = gpio;
    s->slice = pwm_gpio_to_slice_num(gpio);
    s->chan = pwm_gpio_to_channel(gpio);

    pwm_set_enabled(s->slice, false);
    s->on = false;
    s->speed = 0;
    s->resolution = pwm_set_freq_duty(s->slice, s->chan, 50, 0);
    pwm_set_dutyH(s->slice, s->chan, 250);
    if (s->chan)
    {
        pwm_set_output_polarity(s->slice, false, invert);
    }
    else
    {
        pwm_set_output_polarity(s->slice, invert, false);
    }
    s->invert = invert;
}

void ServoOn(Servo *s)
{
    pwm_set_enabled(s->slice, true);
    s->on = true;
}

void ServoOff(Servo *s)
{
    pwm_set_enabled(s->slice, false);
    s->on = false;
}
void ServoPosition(Servo *s, uint p)
{
    pwm_set_dutyH(s->slice, s->chan, p * 10 + 250);
}

int main()
{
    Servo s1;
    ServoInit(&s1, 20, false);

    ServoOn(&s1);
    while (true)
    {
        ServoPosition(&s1, 0);
        sleep_ms(500);
        ServoPosition(&s1, 100);
        sleep_ms(500);
    }

    return 0;
}

Page 173,174  remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"

typedef struct
{
    uint gpio;
    uint speed;
    bool forward;
    uint32_t gpiomask;
    uint phase;
} StepperBi;

uint32_t stepTable[8] = (uint32_t[8]){0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9};
/*
    {1, 0, 0, 0},
    {1, 1, 0, 0},
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 0, 0, 1},
    {1, 0, 0, 1}
*/
void StepperBiInit(StepperBi *s, uint gpio)
{
    s->gpio = gpio;

    for (int i = 0; i < 4; i++)
    {
        gpio_set_function((s->gpio) + i, GPIO_FUNC_SIO);
        gpio_set_dir((s->gpio) + i, true);
    }
    s->gpiomask = 0x0F << gpio;
    volatile uint32_t mask = stepTable[0] << gpio;
    gpio_put_masked(s->gpiomask, mask);
    s->phase = 0;
    s->speed = 0;
    s->forward = true;
}

void setPhase(StepperBi *s, uint p)
{
    uint32_t mask = stepTable[p] << (s->gpio);
    gpio_put_masked(s->gpiomask, mask);
}

void stepForward(StepperBi *s)
{
    s->phase = (s->phase + 1) % 8;
    setPhase(s, s->phase);
}

void stepReverse(StepperBi *s)
{
    s->phase = (s->phase - 1) % 8;
    setPhase(s, s->phase);
}

void rotate(StepperBi *s, bool dir, int speed)
{
    s->forward = dir;
    s->speed = speed;
}

int main()
{
    stdio_init_all();
    StepperBi s1;
    StepperBiInit(&s1, 18);
    while (true)
    {
        stepForward(&s1);
        sleep_ms(1);
    }
    return 0;
}

Page 178 remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"

typedef struct
{
    uint gpio;
    uint speed;
    bool forward;
    uint32_t gpiomask;
    uint phase;
} StepperBi;

uint32_t stepTable[8] = (uint32_t[8]){0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9};
/*
    {1, 0, 0, 0},
    {1, 1, 0, 0},
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 0, 0, 1},
    {1, 0, 0, 1}
*/
void StepperBiInit(StepperBi *s, uint gpio)
{
    s->gpio = gpio;

    for (int i = 0; i < 4; i++)
    {
        gpio_set_function((s->gpio) + i, GPIO_FUNC_SIO);
        gpio_set_dir((s->gpio) + i, true);
    }
    s->gpiomask = 0x0F << gpio;
    volatile uint32_t mask = stepTable[0] << gpio;
    gpio_put_masked(s->gpiomask, mask);
    s->phase = 0;
    s->speed = 0;
    s->forward = true;
}

void setPhase(StepperBi *s, uint p)
{
    uint32_t mask = stepTable[p] << (s->gpio);
    gpio_put_masked(s->gpiomask, mask);
}

void stepForward(StepperBi *s)
{
    s->phase = (s->phase + 1) % 8;
    setPhase(s, s->phase);
}

void stepReverse(StepperBi *s)
{
    s->phase = (s->phase - 1) % 8;
    setPhase(s, s->phase);
}

bool step(struct repeating_timer *t)
{
    StepperBi *s = (StepperBi *)(t->user_data);
    if (s->forward)
    {
        stepForward(s);
    }
    else
    {
        stepReverse(s);
    }
    return true;
}
struct repeating_timer timer;

void rotate(StepperBi *s, bool dir, int speed)
{
    cancel_repeating_timer(&timer);
    s->forward = dir;
    if (speed == 0)
    {
        s->speed = 0;
        return;
    }
    s->speed = 1000 * 1000 / (4 * speed);
    add_repeating_timer_us(s->speed, step, s, &timer);
}

int main()
{
    static StepperBi s1;
    StepperBiInit(&s1, 18);
    rotate(&s1, true, 250);
    while (true)
    {
        rotate(&s1, true, 250);
        sleep_ms(100);
        rotate(&s1, true, 00);
        sleep_ms(100);
    }
    return 0;
}
  

Page 189 remember to add hardware_spi to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"

int main()
{
    stdio_init_all();
    spi_init(spi0, 500 * 1000);
    gpio_set_function(4, GPIO_FUNC_SPI);
    gpio_set_function(6, GPIO_FUNC_SPI);
    gpio_set_function(7, GPIO_FUNC_SPI);
    spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
    uint16_t wBuff[1] = {0xAA};
    uint16_t rBuff[1];

    int n = spi_write16_read16_blocking(spi0, wBuff, rBuff, 1);
    spi_deinit(spi0);
    printf(" %X %X %d ", wBuff[0], rBuff[0], n);
}

Page 196-197 remember to add hardware_spi to the CMakeLists.txt file 

#include <stdio.h>

#include "pico/stdlib.h"
#include "hardware/spi.h"

int main()
{
    stdio_init_all();

    spi_init(spi0, 500 * 1000);
    spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);

    gpio_set_function(16, GPIO_FUNC_SPI);
    gpio_set_function(18, GPIO_FUNC_SPI);
    gpio_set_function(19, GPIO_FUNC_SPI);

    gpio_init(17);
    gpio_set_dir(17, GPIO_OUT);
    gpio_put(17, 1);
    sleep_ms(1);
    uint8_t wBuff[1] = {0xD0};
    uint8_t rBuff[8];

    gpio_put(17, 0);
    sleep_us(1);
    spi_write_blocking(spi0, wBuff, 1);
    spi_read_blocking(spi0, 0, rBuff, 1);
    sleep_us(1);
    gpio_put(17, 1);
    printf("Chip ID is 0x%x\n", rBuff[0]);
    gpio_put(17, 0);
    sleep_us(1);
    wBuff[0] = 0xF2;
    wBuff[1] = 0x1;
    spi_write_blocking(spi0, wBuff, 2);
    wBuff[0] = 0xF4;
    wBuff[1] = 0x27;
    spi_write_blocking(spi0, wBuff, 2);
    gpio_put(17, 1);
    sleep_us(1);

    wBuff[0] = 0xF7;
    gpio_put(17, 0);
    sleep_us(1);
    spi_write_blocking(spi0, wBuff, 1);

    spi_read_blocking(spi0, 0, rBuff, 8);
    sleep_us(1);
    gpio_put(17, 1);

    uint32_t pressure = ((uint32_t)rBuff[0] << 12) | ((uint32_t)rBuff[1] << 4) | (rBuff[2] >> 4);
    uint32_t temperature = ((uint32_t)rBuff[3] << 12) | ((uint32_t)rBuff[4] << 4) | (rBuff[5] >> 4);
    uint32_t humidity = (uint32_t)rBuff[6] << 8 | rBuff[7];

    printf("Humidity = %d\n", humidity);
    printf("Pressure = %d\n", pressure);
    printf("Temp. = %d\n", temperature);
}

Page 203 remember to add hardware_adc to the CMakeLists.txt file 

#include
#include "pico/stdlib.h"
#include "hardware/adc.h"
int main()
{
stdio_init_all();
adc_init();
adc_gpio_init(26);
adc_gpio_init(27);

while (1)
{
const float conversion_factor = 3.3f / (1 << 12);
adc_select_input(0);
uint16_t result = adc_read();
printf("Raw value 0: 0x%03x, voltage: %f V\n",
result, result * conversion_factor);
adc_select_input(1);
result = adc_read();
printf("Raw value 1: 0x%03x, voltage: %f V\n",
result, result * conversion_factor);
sleep_ms(500);
}
}

Page 205 remember to add hardware_adc to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"

int main()
{
    stdio_init_all();

    adc_init();
    adc_gpio_init(26);
    adc_gpio_init(27);
    adc_set_round_robin(0x03);
    adc_fifo_setup(true, false, 0, false, false);
    adc_run(true);
    const float conversion_factor = 3.3f / (1 << 12);
    while (1)
    {
        uint16_t result = adc_fifo_get();
        printf("Raw value 0: 0x%03x, voltage: %f V\n", result, result * conversion_factor);
        int level = adc_fifo_get_level();
        printf("level: %d \n", level);
    }
}

Page 211 remember to add hardware_spi to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"

int main()
{
    stdio_init_all();
    spi_init(spi0, 500 * 1000);
    spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
    gpio_set_function(16, GPIO_FUNC_SPI);
    gpio_set_function(18, GPIO_FUNC_SPI);
    gpio_set_function(19, GPIO_FUNC_SPI);
    gpio_init(17);
    gpio_set_dir(17, GPIO_OUT);
    gpio_put(17, 1);
    sleep_ms(1);
    uint16_t wBuff[3] = {0x01, 0x80, 0x00};
    uint16_t rBuff[3];
    gpio_put(17, 0);
    int n = spi_write16_read16_blocking(spi0, wBuff, rBuff, 3);
    sleep_us(1);
    gpio_put(17, 1);
    int data = ((int)rBuff[1] & 0x03) << 8 | (int)rBuff[2];
    float volts = (float)data * 3.3f / 1023.0f;
    printf("%f V\n", volts);
}

 

Page 227 remember to add hardware_i2c to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"

int main()
{
    stdio_init_all();

    i2c_init(i2c0, 100 * 1000);

    gpio_set_function(4, GPIO_FUNC_I2C);
    gpio_set_function(5, GPIO_FUNC_I2C);
    uint8_t buf[] = {0xE7};

    i2c_write_blocking(i2c0, 0x40, buf, 1, false);
    i2c_read_blocking(i2c0, 0x40, buf, 1, false);
    printf("User Register = %X \r\n", buf[0]);
}

Page 228 remember to add hardware_i2c to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"

int main()
{
    stdio_init_all();

    i2c_init(i2c0, 100 * 1000);

    gpio_set_function(4, GPIO_FUNC_I2C);
    gpio_set_function(5, GPIO_FUNC_I2C);

    uint8_t buf[4] = {0xE3};
    i2c_write_blocking(i2c0, 0x40, buf, 1, true);
    i2c_read_blocking(i2c0, 0x40, buf, 3, false);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
};

Page 233 remember to add hardware_i2c to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
    uint32_t data32 = ((uint32_t)msb << 16) | ((uint32_t)lsb << 8) |
                      (uint32_t)check;
    uint32_t divisor = 0x988000;
    for (int i = 0; i < 16; i++)
    {
        if (data32 & (uint32_t)1 << (23 - i))
            data32 ^= divisor;
        divisor >>= 1;
    };
    return (uint8_t)data32;
}
int main()
{
    stdio_init_all();

    i2c_init(i2c0, 100 * 1000);

    gpio_set_function(4, GPIO_FUNC_I2C);
    gpio_set_function(5, GPIO_FUNC_I2C);

    uint8_t buf[4] = {0xE3};
    i2c_write_blocking(i2c0, 0x40, buf, 1, true);
    i2c_read_blocking(i2c0, 0x40, buf, 3, false);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    unsigned int data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    float temp = (float)(-46.85 + (175.72 * data16 / (float)65536));
    printf("Temperature %f C \n\r", temp);

    buf[0] = 0xF5;
    i2c_write_blocking(i2c0, 0x40, buf, 1, true);
    while (i2c_read_blocking(i2c0, 0x40, buf, 3, false) < 0)
    {
        sleep_ms(1);
    };

    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float hum = -6 + (125.0 * (float)data16) / 65536;
    printf("Humidity %f %% \n\r", hum);
 
 

Page 240

.program squarewave
    set pindirs, 1   ; Set pin to output
again:
    set pins, 1      ; Drive pin high
    set pins, 0      ; Drive pin low
    jmp again        ; Set PC to label `again`

Page 241

cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
pico_sdk_init()

project(pioBlinky C CXX ASM)
add_executable(pio
 pio.c
)
pico_generate_pio_header(pio ${CMAKE_CURRENT_LIST_DIR}/sqwave.pio)

target_link_libraries(pio  pico_stdlib hardware_pio)
pico_add_extra_outputs(pio)

Page 243 remember to use the CMakeLists.txt file and the PIO program given earlier 

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{
    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);

    sm_config_set_set_pins(&c, 2, 1);
    pio_gpio_init(pio0, 2);

    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);
    return 0;
}

Page 247

PIO Program
.program squarewave
    set pindirs, 1  
    pull block
again:
    set pins, 1 
    mov x, osr
 loop1: 
     jmp x--,loop1
    set pins, 0 
    mov x, osr
 loop2:  
   jmp x--,loop2 
jmp again
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"

#include "sqwave.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);

    sm_config_set_set_pins(&c, 2, 1);
    pio_gpio_init(pio0, 2);

    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    pio_sm_put_blocking(pio0, sm, 0xFFFF);
    return 0;
}

Page 249-250

PIO Program

.program squarewave

    set pindirs, 3  
    pull block    
again:
    out pins,2
    jmp again 
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_set_pins(&c, 2, 2);
    sm_config_set_out_pins(&c, 2, 2);
    pio_gpio_init(pio0, 2);
    pio_gpio_init(pio0, 3);

    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    pio_sm_put_blocking(pio0, sm, 0xFEDCBA98);
    return 0;
}

Page 251-252

PIO Program

.program squarewave   
again:
  out pins,2
  jmp again 
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{
    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_set_pins(&c, 2, 2);
    sm_config_set_out_pins(&c, 2, 2);
    pio_gpio_init(pio0, 2);
    pio_gpio_init(pio0, 3);
    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 2, true);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    sm_config_set_out_shift(&c, true, true, 6);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);
    while (true)
    {
        pio_sm_put_blocking(pio0, sm, 0xFEDCBA98);
    }
    return 0;
}

Page  253-254

PIO Program
.program squarewave   
.side_set 1 opt
again:
  nop side 1
  jmp  again side 0 

C Program

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{
    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_sideset_pins(&c, 2);
    pio_gpio_init(pio0, 2);
    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, true);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    pio_sm_init(pio0, sm, offset, &c);

    pio_sm_set_enabled(pio0, sm, true);
    return 0;
}

Page 256-257

PIO Program
.program light  
again:
  in pins,1
  push block
  jmp  again  

C Program

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "light.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &light_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = light_program_get_default_config(offset);

    sm_config_set_in_pins(&c, 2);
    pio_gpio_init(pio0, 2);

    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, false);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);

    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);
    while (true)
    {
        uint32_t flag = pio_sm_get_blocking(pio0, sm);
        if (flag == 0)
        {
            gpio_put(25, 0);
        }
        else
        {
            gpio_put(25, 1);
        }
    }

    return 0;
}

Page 258-259

PIO Program

.program squarewave  
again:
   wait 0 pin 0
   wait 1 pin 0
   set pins, 1  
   set pins, 0  
jmp  again
  
CProgram
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &squarewave_program);
    uint sm = pio_claim_unused_sm(pio0, true);

    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_set_pins(&c, 3, 1);
    sm_config_set_in_pins(&c, 2);

    pio_gpio_init(pio0, 2);
    pio_gpio_init(pio0, 3);
    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, false);
    pio_sm_set_consecutive_pindirs(pio0, sm, 3, 1, true);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);

    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    return 0;
}
 
 
Page 267
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int main()
{
    stdio_init_all();
    gpio_init(2);
    gpio_set_dir(2, GPIO_OUT);
    gpio_put(2, 1);
    sleep_ms(1);
    gpio_put(2, 0);
    sleep_ms(1);
    gpio_set_dir(2, GPIO_IN);
    return 0;
}

Page 270-271

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

inline static void WaitFallingEdge(uint gpio)
{
    while (gpio_get(gpio) == 1)
    {
    };
    while (gpio_get(gpio) == 0)
    {
    };
}

uint32_t getData(uint gpio)
{
    uint32_t t2;
    uint32_t data = 0;
    uint32_t t1 = time_us_32();
    for (int i = 0; i < 32; i++)
    {
        WaitFallingEdge(2);
        t2 = time_us_32();
        data = data << 1;
        data = data | ((t2 - t1) > 100);
        t1 = t2;
    }
    return data;
}
uint8_t getCheck(uint gpio)
{
    uint8_t checksum = 0;
    uint32_t t2;
    uint32_t t1 = time_us_32();
    for (int i = 0; i < 8; i++)
    {
        WaitFallingEdge(2);
        t2 = time_us_32();
        checksum = checksum << 1;
        checksum = checksum | (t2 - t1) > 100;
        t1 = t2;
    }
    return checksum;
}

void dhtInitalize(uint gpio)
{
    gpio_init(gpio);
    gpio_set_dir(gpio, GPIO_OUT);
    gpio_put(gpio, 1);
    sleep_ms(1);
    gpio_put(gpio, 0);
    sleep_ms(1);
    gpio_set_dir(gpio, GPIO_IN);
    for (int i = 0; i < 2; i++)
    {
        WaitFallingEdge(gpio);
    }
}

typedef struct
{
    float temperature;
    float humidity;
    bool error;
} dhtData;

void dhtread(uint gpio, dhtData *reading)
{
    dhtInitalize(gpio);
    uint32_t data = getData(gpio);
    uint8_t checksum = getCheck(gpio);
    uint8_t byte1 = (data >> 24 & 0xFF);
    uint8_t byte2 = (data >> 16 & 0xFF);
    uint8_t byte3 = (data >> 8 & 0xFF);
    uint8_t byte4 = (data & 0xFF);

    reading->error = (checksum != ((byte1 + byte2 + byte3 + byte4) & 0xFF));
    reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;

    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        reading->temperature = -reading->temperature;
}

int main()
{
    stdio_init_all();
    printf("data^^^^^\n");
    dhtData reading;
    dhtread(2, &reading);
    printf("Humidity= %f %\n", reading.humidity);
    printf("Temperature= %f C\n", reading.temperature);
    return 0;
}

Page 275-277

PIO Program

.program dht
    set pins, 1 
    set pindirs, 1    
again:
  pull block
  set pins, 0
mov x, osr
loop1: 
    jmp x--,loop1
set pindirs, 0 
wait 1 pin 0
wait 0 pin 0
wait 1 pin 0
wait 0 pin 0

    set y,31
bits:
    wait 1 pin 0
    set x, 0
loop2:
        jmp x--,continue
continue: jmp pin,loop2 
        in x,4  
    jmp y--,bits

    set y,7
check:
    wait 1 pin 0
    set x, 0
loop3:
        jmp x--,continue2
continue2: jmp pin,loop3
        in x,4  
    jmp y--,check
jmp again

C Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"

#include "DHT.pio.h"
uint dhtInitalize(PIO pio, int gpio)
{

    uint offset = pio_add_program(pio, &dht_program);

    uint sm = pio_claim_unused_sm(pio, true);
    pio_gpio_init(pio, gpio);
    pio_sm_config c = dht_program_get_default_config(offset);
    sm_config_set_clkdiv_int_frac(&c, 128, 0);

    sm_config_set_set_pins(&c, gpio, 1);
    sm_config_set_in_pins(&c, gpio);

    sm_config_set_jmp_pin(&c, gpio);
    sm_config_set_in_shift(&c, true, true, 32);
    pio_sm_init(pio0, sm, offset, &c);

    pio_sm_set_enabled(pio0, sm, true);
    return sm;
}

uint8_t getByte(PIO pio, uint sm)
{
    uint32_t count = pio_sm_get_blocking(pio0, sm);
    uint8_t byte = 0;
    for (int i = 0; i < 8; i++)
    {
        byte = byte << 1;
        if (((count >> i * 4) & 0x0F) > 8)
        {
            byte = byte | 1;
        }
    }
    return byte;
}

typedef struct
{
    float temperature;
    float humidity;
    bool error;
} dhtData;

void dhtread(PIO pio, uint sm, dhtData *reading)
{

    pio_sm_put_blocking(pio, sm, 1000);

    uint8_t byte1 = getByte(pio, sm);
    uint8_t byte2 = getByte(pio, sm);
    uint8_t byte3 = getByte(pio, sm);
    uint8_t byte4 = getByte(pio, sm);

    uint8_t checksum = getByte(pio, sm);

    reading->error = (checksum == (byte1 + byte2 + byte3 + byte4) & 0xFF);
    reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;

    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        reading->temperature = -reading->temperature;
}

int main()
{
    stdio_init_all();
    uint sm = dhtInitalize(pio0, 2);
    dhtData reading;
    dhtread(pio0, sm, &reading);
    printf("Humidity= %f %\n", reading.humidity);
    printf("Temperature= %f C\n", reading.temperature);
    return 0;
}

Page 281-283

PIO Program
.program dht
 set pins, 1 
 set pindirs, 1 
again:
 pull block
 set pins, 0
mov x, osr
loop1: 
 jmp x--,loop1
set pindirs, 0 
wait 1 pin 0
wait 0 pin 0
wait 1 pin 0
wait 0 pin 0

set y,31
bits:
 wait 1 pin 0 [25]
 in pins,1 
 wait 0 pin 0
 jmp y--,bits

 set y,7
check:
wait 1 pin 0 [25]
 in pins,1 
 wait 0 pin 0 
 jmp y--,check
push block
jmp again

C Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"

#include "DHT.pio.h"
uint dhtInitalize(PIO pio, int gpio)
{

    uint offset = pio_add_program(pio, &dht_program);

    uint sm = pio_claim_unused_sm(pio, true);
    pio_gpio_init(pio, gpio);

    pio_sm_config c = dht_program_get_default_config(offset);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    sm_config_set_set_pins(&c, gpio, 1);
    sm_config_set_in_pins(&c, gpio);
    sm_config_set_in_shift(&c, false, true, 32);
    pio_sm_init(pio0, sm, offset, &c);

    pio_sm_set_enabled(pio0, sm, true);
    return sm;
}

typedef struct
{
    float temperature;
    float humidity;
    bool error;
} dhtData;

void dhtread(PIO pio, uint sm, dhtData *reading)
{
    pio_sm_put_blocking(pio, sm, 500);

    uint32_t data = pio_sm_get_blocking(pio0, sm);
    uint8_t byte1 = (data >> 24 & 0xFF);
    uint8_t byte2 = (data >> 16 & 0xFF);
    uint8_t byte3 = (data >> 8 & 0xFF);
    uint8_t byte4 = (data & 0xFF);
    uint8_t checksum = pio_sm_get_blocking(pio0, sm) & 0xFF;

    reading->error = (checksum != ((byte1 + byte2 + byte3 + byte4) & 0xFF));
    reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;

    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        reading->temperature = -reading->temperature;
}

int main()
{
    stdio_init_all();
    uint sm = dhtInitalize(pio0, 2);
    dhtData reading;
    dhtread(pio0, sm, &reading);
    printf("Humidity= %f %\n", reading.humidity);
    printf("Temperature= %f C\n", reading.temperature);
    return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)


project(dht C CXX ASM)
pico_sdk_init()
add_executable(dht
 DHT.c
)
pico_generate_pio_header(dht ${CMAKE_CURRENT_LIST_DIR}/DHT.pio)
target_link_libraries(dht  pico_stdlib hardware_pio)
pico_add_extra_outputs(dht)  

Page 300-303

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int presence(uint8_t pin)
{
    gpio_set_dir(2, GPIO_OUT);
    gpio_put(pin, 1);
    sleep_ms(1);
    gpio_put(pin, 0);
    sleep_us(480);
    gpio_set_dir(pin, GPIO_IN);
    sleep_us(70);
    int b = gpio_get(pin);
    sleep_us(410);
    return b;
}

void writeBit(uint8_t pin, int b)
{
    int delay1, delay2;
    if (b == 1)
    {
        delay1 = 6;
        delay2 = 64;
    }
    else
    {
        delay1 = 60;
        delay2 = 10;
    }
    gpio_set_dir(pin, GPIO_OUT);
    gpio_put(pin, 0);
    sleep_us(delay1);
    gpio_set_dir(pin, GPIO_IN);
    sleep_us(delay2);
}

void writeByte(uint8_t pin, int byte)
{
    for (int i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {
            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

uint8_t readBit(uint8_t pin)
{
    gpio_set_dir(pin, GPIO_OUT);
    gpio_put(pin, 0);
    sleep_us(8);
    gpio_set_dir(pin, GPIO_IN);
    sleep_us(2);
    uint8_t b = gpio_get(pin);
    sleep_us(60);
    return b;
}

int readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}

int convert(uint8_t pin)
{
    writeByte(pin, 0x44);
    int i;
    for (i = 0; i < 500; i++)
    {
        sleep_ms(10);
        if (readBit(pin) == 1)
            break;
    }
    return i;
}

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;

            databyte >>= 1;
        }
    }

    return crc;
}

float getTemperature(uint8_t pin)
{
    if (presence(pin) == 1)
        return -1000;
    writeByte(pin, 0xCC);
    if (convert(pin) == 500)
        return -3000;
    presence(pin);
    writeByte(pin, 0xCC);
    writeByte(pin, 0xBE);
    int i;
    uint8_t data[9];
    for (i = 0; i < 9; i++)
    {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float)temp1 / 16;
    return temp;
}

int main()
{
    stdio_init_all();
    gpio_init(2);

    if (presence(2) == 1)
    {
        printf("No device \n");
    }
    float t;
    for (;;)
    {
        do
        {
            t = getTemperature(2);
        } while (t < -999);
        printf("%f\r\n", t);
        sleep_ms(500);
    };

    return 0;
}

Page 309-312

PIO Program

.program DS1820 
.wrap_target
again:
  pull block
  mov x, osr
  jmp !x, read

write:  set pindirs, 1 
  set pins, 0  
loop1: 
    jmp x--,loop1
set pindirs, 0 [31]
wait 1 pin 0 [31]

  pull block
  mov x, osr
bytes1:
   pull block
  set y, 7    
  set pindirs, 1 
bit1:
  set pins, 0 [1]
  out pins,1 [31]
    set pins, 1 [20]
   jmp y--,bit1
jmp x--,bytes1

set pindirs, 0 [31]
jmp again

read:
  pull block
  mov x, osr
bytes2:
  set y, 7
bit2:
  set pindirs, 1 
  set pins, 0 [1]  
  set pindirs, 0 [5]
  in pins,1 [10]   
jmp y--,bit2
jmp x--,bytes2
.wrap

C Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "DS1820.pio.h"

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;

            databyte >>= 1;
        }
    }

    return crc;
}

void writeBytes(PIO pio, uint sm, uint8_t bytes[], int len)
{
    pio_sm_put_blocking(pio, sm, 250);
    pio_sm_put_blocking(pio, sm, len - 1);
    for (int i = 0; i < len; i++)
    {
        pio_sm_put_blocking(pio, sm, bytes[i]);
    }
}
void readBytes(PIO pio, uint sm, uint8_t bytes[], int len)
{
    pio_sm_put_blocking(pio, sm, 0);
    pio_sm_put_blocking(pio, sm, len - 1);
    for (int i = 0; i < len; i++)
    {
        bytes[i] = pio_sm_get_blocking(pio, sm) >> 24;
    }
}

float getTemperature(PIO pio, uint sm)
{
    writeBytes(pio, sm, (uint8_t[]){0xCC, 0x44}, 2);
    sleep_ms(1000);
    writeBytes(pio, sm, (uint8_t[]){0xCC, 0xBE}, 2);

    uint8_t data[9];
    readBytes(pio, sm, data, 9);

    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    volatile float temp = (float)temp1 / 16;
    return temp;
}

uint DS18Initalize(PIO pio, int gpio)
{

    uint offset = pio_add_program(pio, &DS1820_program);

    uint sm = pio_claim_unused_sm(pio, true);
    pio_gpio_init(pio, gpio);

    pio_sm_config c = DS1820_program_get_default_config(offset);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    sm_config_set_set_pins(&c, gpio, 1);
    sm_config_set_out_pins(&c, gpio, 1);
    sm_config_set_in_pins(&c, gpio);
    sm_config_set_in_shift(&c, true, true, 8);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);
    return sm;
}

int main()
{
    stdio_init_all();

    uint sm = DS18Initalize(pio0, 2);

    float t;
    for (;;)
    {
        do
        {
            t = getTemperature(pio0, sm);
        } while (t < -999);
        printf("temperature %f\r\n", t);
        sleep_ms(500);
    };

    return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(ds18 C CXX ASM)
pico_sdk_init()
add_executable(ds18
 DS1820.c
)
pico_generate_pio_header(ds18 ${CMAKE_CURRENT_LIST_DIR}/DS1820.pio)
target_link_libraries(ds18  pico_stdlib hardware_gpio hardware_pio)
pico_add_extra_outputs(ds18) 
 
 

Page 322

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int main()
{
    stdio_init_all();
    uart_init(uart1, 9600);
    gpio_set_function(4, GPIO_FUNC_UART);
    gpio_set_function(5, GPIO_FUNC_UART);
    uart_set_format(uart1, 8, 1, UART_PARITY_EVEN);
    uint8_t SendData[] = "Hello World";
    uint8_t RecData[20];
    uart_write_blocking(uart1, SendData, 11);
    uart_read_blocking(uart1, RecData, 11);
    RecData[11] = 0;
    printf("%s", RecData);
}

Page 330

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/adc.h"

int main()
{
    stdio_init_all();
    adc_init();
    adc_select_input(3);
    uint16_t result = adc_read();
    if (result < 0xFF) {
        printf("Pico W\n");
    }else{
        printf("Pico\n");
    };
}

Page 335

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"


int setup(uint32_t country, const char *ssid, const char *pass, uint32_t auth)
{

 if (cyw43_arch_init_with_country(country))
 {
 return 1;
 }
 cyw43_arch_enable_sta_mode();
 if (cyw43_arch_wifi_connect_blocking(ssid, pass, auth))
 {
 return 2;
 }
}

char ssid[] = "myhost";
char pass[] = "mypassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;

int main()
{
    stdio_init_all();
    setup(country, ssid, pass, auth);
    while (true)
    {
        sleep_ms(1);
    }
}

Page 336

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()


add_executable(picow
 picow.c
)

target_include_directories(picow PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(picow pico_stdlib
                        pico_cyw43_arch_lwip_threadsafe_background)
pico_add_extra_outputs(picow)

Page 337

int setup(uint32_t country, const char *ssid, const char *pass, uint32_t auth)
{

    if (cyw43_arch_init_with_country(country))
    {
        return 1;
    }
    cyw43_arch_enable_sta_mode();

    if (cyw43_arch_wifi_connect_async(ssid, pass, auth))
    {
        return 2;
    }
    int flashrate = 1000;
    int status = CYW43_LINK_UP + 1;
    while (status >= 0 && status != CYW43_LINK_UP)
    {
        int new_status = cyw43_tcpip_link_status(&cyw43_state,  CYW43_ITF_STA);
        if (new_status != status)
        {
            status = new_status;
            flashrate = flashrate / (status + 1);
            printf("connect status: %d %d\n", status, flashrate);
        }
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(flashrate);
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(flashrate);
    }
    if (status < 0)
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
    }
    else
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
    }
    return status;
}

Page 339-340

int setup(uint32_t country, const char *ssid, const char *pass,
          uint32_t auth, const char *hostname, ip_addr_t *ip,
          ip_addr_t *mask, ip_addr_t *gw)
{

    if (cyw43_arch_init_with_country(country))
    {
        return 1;
    }

    cyw43_arch_enable_sta_mode();
    if (hostname != NULL)
    {
        netif_set_hostname(netif_default, hostname);
    }
    if (cyw43_arch_wifi_connect_async(ssid, pass, auth))
    {
        return 2;
    }
    int flashrate = 1000;
    int status = CYW43_LINK_UP + 1;
    while (status >= 0 && status != CYW43_LINK_UP)
    {
        int new_status = cyw43_tcpip_link_status(&cyw43_state,
                                                 CYW43_ITF_STA);
        if (new_status != status)
        {
            status = new_status;
            flashrate = flashrate / (status + 1);
            printf("connect status: %d %d\n", status, flashrate);
        }
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(flashrate);
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(flashrate);
    }
    if (status < 0)
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
    }
    else
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        if (ip != NULL)
        {
            netif_set_ipaddr(netif_default, ip);
        }
        if (mask != NULL)
        {
            netif_set_netmask(netif_default, mask);
        }
        if (gw != NULL)
        {
            netif_set_gw(netif_default, gw);
        }

        printf("IP: %s\n",
               ip4addr_ntoa(netif_ip_addr4(netif_default)));
        printf("Mask: %s\n",
               ip4addr_ntoa(netif_ip_netmask4(netif_default)));
        printf("Gateway: %s\n",
               ip4addr_ntoa(netif_ip_gw4(netif_default)));
        printf("Host Name: %s\n",
               netif_get_hostname(netif_default));
    }
    return status;
}

Page 346 - corrected to free pbuf see errata 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/apps/http_client.h"

char myBuff[1000];

void result(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err)
{
    printf("transfer complete\n");
    printf("local result=%d\n", httpc_result);
    printf("http result=%d\n", srv_res);
}

err_t headers(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len)
{
    printf("headers recieved\n");
    printf("content length=%d\n", content_len);
    printf("header length %d\n", hdr_len);

    pbuf_copy_partial(hdr, myBuff, hdr->tot_len, 0);
    printf("headers \n");
    printf("%s", myBuff);
    return ERR_OK;
}

err_t body(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err)
{
    printf("body\n");
    pbuf_copy_partial(p, myBuff, p->tot_len, 0);
    printf("%s", myBuff);

    return ERR_OK;
}

char ssid[] = "mySSID";
char pass[] = "myPassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
int main()
{
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);
    uint16_t port = 80;
    httpc_connection_t settings;
    settings.result_fn = result;
    settings.headers_done_fn = headers;

    err_t err = httpc_get_file_dns(
        "example.com",
        80,
        "/index.html",
        &settings,
        body,
        NULL,
        NULL);
    printf("status %d \n", err);
    while (true)
    {
        sleep_ms(500);
    }
}

void result(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err)
{
    printf("transfer complete\n");
    printf("local result=%d\n", httpc_result);
    printf("http result=%d\n", srv_res);
}

err_t headers(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len)
{
    printf("headers recieved\n");
    printf("content length=%d\n", content_len);
    printf("header length %d\n", hdr_len);

    pbuf_copy_partial(hdr, myBuff, hdr->tot_len, 0);
    printf("headers \n");
    printf("%s", myBuff);
    return ERR_OK;
}

err_t body(void *arg, struct altcp_pcb *conn, struct pbuf *p, err_t err)
{
    printf("body\n");
    pbuf_copy_partial(p, myBuff, p->tot_len, 0);
    pbuf_free(p);
    printf("%s", myBuff);
    return ERR_OK;
}

char ssid[] = "mySSID";
char pass[] = "myPassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
int main()
{
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);
    uint16_t port = 80;
    httpc_connection_t settings;
    settings.result_fn = result;
    settings.headers_done_fn = headers;

    err_t err = httpc_get_file_dns(
        "example.com",
        80,
        "/index.html",
        &settings,
        body,
        NULL,
        NULL);
    printf("status %d \n", err);
    while (true)
    {
        sleep_ms(500);
    }
}

Page 347

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/apps/httpd.h"

char ssid[] = "myssid";
char pass[] = "mypassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
int main()
{
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);
    httpd_init();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 349

cmake_minimum_required(VERSION 3.13)
project(makefsdata C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

add_executable(htmlgen
 makefsdata.c
)

target_include_directories(htmlgen
         PRIVATE ../../../../src/include/
         PRIVATE ../../../../contrib/ports/unix/port/include/
         PRIVATE ${CMAKE_CURRENT_LIST_DIR})

Page 354

C File 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/apps/httpd.h"

int setup(uint32_t country, const char *ssid, const char *pass, uint32_t auth, const char *hostname, ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
{

    if (cyw43_arch_init_with_country(country))
    {
        return 1;
    }

    cyw43_arch_enable_sta_mode();
    if (hostname != NULL)
    {
        netif_set_hostname(netif_default, hostname);
    }
    if (cyw43_arch_wifi_connect_async(ssid, pass, auth))
    {
        return 2;
    }
    int flashrate = 1000;
    int status = CYW43_LINK_UP + 1;
    while (status >= 0 && status != CYW43_LINK_UP)
    {
        int new_status = cyw43_tcpip_link_status(&cyw43_state, CYW43_ITF_STA);
        if (new_status != status)
        {
            status = new_status;
            flashrate = flashrate / (status + 1);
            printf("connect status: %d %d\n", status, flashrate);
        }
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(flashrate);
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(flashrate);
    }
    if (status < 0)
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
    }
    else
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);

        if (ip != NULL)
        {
            netif_set_ipaddr(netif_default, ip);
        }
        if (mask != NULL)
        {
            netif_set_netmask(netif_default, mask);
        }
        if (gw != NULL)
        {
            netif_set_gw(netif_default, gw);
        }

        printf("IP: %s\n", ip4addr_ntoa(netif_ip_addr4(netif_default)));
        printf("Mask: %s\n", ip4addr_ntoa(netif_ip_netmask4(netif_default)));
        printf("Gateway: %s\n", ip4addr_ntoa(netif_ip_gw4(netif_default)));
        printf("Host Name: %s\n", netif_get_hostname(netif_default));
    }
    return status;
}

const char *ssitags[] = {"temp", "hum"};

u16_t mySSIHandler(int iIndex, char *pcInsert, int iInsertLen)
{
    switch (iIndex)
    {
    case 0:
        snprintf(pcInsert, iInsertLen, "42 C");
        break;
    case 1:
        snprintf(pcInsert, iInsertLen, "80%%");
        break;
    }
}

char ssid[] = "mySSDI";
char pass[] = "myPassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
int main()
{
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);
    http_set_ssi_handler(mySSIHandler, ssitags, 2);
    httpd_init();

    while (true)
    {
        sleep_ms(500);
    }
}
CMAKE file
cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(picow
 picow.c
)

target_include_directories(picow PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(picow pico_stdlib
        pico_cyw43_arch_lwip_threadsafe_background pico_lwip_http)
pico_add_extra_outputs(picow)

Page 363

#include "pico/stdlib.h"
#include "hardware/gpio.h"

int main()
{  
    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);

    uint32_t *SIO = (uint32_t *)0xd0000000;
    while (true)
    {
        *(SIO + 0x014 / 4) = 1ul << 25;
        sleep_ms(500);
        *(SIO + 0x018 / 4) = 1ul << 25;
        sleep_ms(500);
    }
}

Programming the Raspberry Pi Pico in C

pico360

 

We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.

The best solution is to provide the source code of the programs in a form that can be copied and pasted into a NetBeans of VS Code project. 

The only downside is that you have to create a project to paste the code into.

To do this follow the instructions in the book.

All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book. This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.

If anything you consider important is missing or if you have any requests or comments  contact:

This email address is being protected from spambots. You need JavaScript enabled to view it. 

Page 28

#include "pico/stdlib.h"

int main() {
    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);
    while (true) {
        gpio_put(25, 1);
        sleep_ms(500);
        gpio_put(25, 0);
        sleep_ms(500);
    }
}

Page 29

cmake_minimum_required(VERSION 3.13)
include(pico_sdk_import.cmake)
project(blinky C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
add_executable(blinky
 blinky.c
)
target_link_libraries(blinky pico_stdlib)
pico_add_extra_outputs(blinky)

Page 34

{
"version": "0.2.0",
"configurations": [
{
"name": "Cortex Debug",
"cwd": "${workspaceRoot}",
"executable": "${command:cmake.launchTargetPath}",
"request": "launch",
"type": "cortex-debug",
"servertype": "openocd",
"gdbPath": "gdb-multiarch",
"device": "RP2040",
"configFiles": [
"interface/raspberrypi-swd.cfg",
"target/rp2040.cfg"
],
"svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
"runToMain": true,
// Give restart the same functionality as runToMain
"postRestartCommands": [
"break main",
"continue"
]
}
]
}

Page 38

{
    "version": "0.2.0",
    "configurations": [        

        {
            "name": "Pico Debug",
            "cwd": "${workspaceRoot}",
            "executable": "${command:cmake.launchTargetPath}",
            "request": "launch",
            "type": "cortex-debug",
            "servertype": "openocd",
            "gdbPath": "arm-none-eabi-gdb",
            "device": "RP2040",
            "configFiles": [
                "interface/picoprobe.cfg",
                "target/rp2040.cfg"
            ],
            "svdFile": "${env:PICO_SDK_PATH}/src/rp2040/hardware_regs/rp2040.svd",
            "runToMain": true,
            // Work around for stopping at main on restart
            "postRestartCommands": [
                "break main",
                "continue"
            ]
        }
    ]
}

Page 46

#include "pico/stdlib.h"

int main()
{
    gpio_init(22);
    gpio_set_dir(22, true);
    while (true)
    {
        gpio_put(22, 1);
        sleep_ms(1000);
        gpio_put(22, 0);
        sleep_ms(1000);
    }
}

Page 81

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_up(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);

    while (true)
    {
        if (gpio_get(21))
        {
            gpio_put(22, 0);
        }
        else
        {
            gpio_put(22, 1);
        }
    }
}

Page 83

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_down(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_put(22, 0);
    while (true)
    {
        while (gpio_get(21) == 0)
        {
        };
        while (gpio_get(21) == 1)
        {
        };
        gpio_put(22, 1);
        sleep_ms(1000);
        gpio_put(22, 0);
    }
}

Page 84

#include "pico/stdlib.h"
int main()
{
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, false);
    gpio_pull_down(21);

    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, true);
    gpio_put(22, 0);

    uint64_t t;

    while (true)
    {
        while (gpio_get(21) == 0)
        {
        };
        t = time_us_64();
        sleep_ms(1);
        while (gpio_get(21) == 1)
        {
        };
        t = (uint64_t)(time_us_64() - t);
        if (t < 2000 * 1000)
        {
            gpio_put(22, 1);
            sleep_ms(1000);
            gpio_put(22, 0);
        }
        else
        {
            for (int i = 0; i < 10; i++)
            {
                gpio_put(22, 1);
                sleep_ms(100);
                gpio_put(22, 0);
                sleep_ms(100);
            }
        }
    }
}

Page 86

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;

    while (true)
    {
        while (gpio_get(22) == 1)
        {
        };
        while (gpio_get(22) == 0)
        {
        };
        t = time_us_64();
        while (gpio_get(22) == 1)
        {
        };
        t = (uint64_t)(time_us_64() - t);
        printf("%llu\n", t);
        sleep_ms(1000);
    }
}

Page 89

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;
    int s = 0;
    int i;
    int count = 0;
    while (true)
    {
        i = gpio_get(22);
        t = time_us_64() + 100;
        switch (s)
        {
        case 0: //button not pushed
            if (i)
            {
                s = 1;
                count++;
                printf("Button Push %d \n\r", count);
            }
            break;
        case 1: //Button pushed
            if (!i)
            {
                s = 0;
            }
            break;
        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t});
    }
}

Page 91

#include <stdio.h>
#include "pico/stdlib.h"
int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    uint64_t t;
    uint64_t tpush, twait;
    int s = 0, i;
    int count = 0;
    while (true)
    {
        i = gpio_get(22);
        t = time_us_64();
        switch (s)
        {
        case 0: //button not pushed
            if (i)
            {
                s = 1;
                tpush = t;
            }
            break;
        case 1: //Button pushed
            if (!i)
            {
                s = 0;
                if ((t - tpush) > 2000000)
                {
                    printf("Button held \n\r");
                }
                else
                {
                    printf("Button pushed \n\r");
                }
                fflush(stdout);
            }
            break;
        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t + 1000});
    }
}

Page 93

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_set_function(21, GPIO_FUNC_SIO);
    gpio_set_dir(21, true);
    gpio_set_function(20, GPIO_FUNC_SIO);
    gpio_set_dir(20, true);
    gpio_set_function(19, GPIO_FUNC_SIO);
    gpio_set_dir(19, true);

    gpio_put(19, 1);
    gpio_put(20, 0);
    gpio_put(21, 0);

    uint64_t t, tpush, twait;
    int s = 0;
    int buttonState = gpio_get(22);
    int edge;
    int buttonNow;

    while (true)
    {
        t = time_us_64();
        buttonNow = gpio_get(22);
        edge = buttonState - buttonNow;
        buttonState = buttonNow;
        switch (s)
        {
        case 0:
            if (edge == 1)
            {
                s = 1;
                gpio_put(19, 0);
                gpio_put(20, 1);
                gpio_put(21, 0);
            }
            break;
        case 1:
            if (edge == 1)
            {
                s = 2;
                gpio_put(19, 0);
                gpio_put(20, 0);
                gpio_put(21, 1);
            }
            break;
        case 2:
            if (edge == 1)
            {
                s = 0;
                gpio_put(19, 1);
                gpio_put(20, 0);
                gpio_put(21, 0);
            }
            break;

        default:
            s = 0;
        }
        sleep_until((absolute_time_t){t + 1000});
    }
}

Page 100

uint32_t gpio_get_events(uint gpio)
{
    int32_t mask = 0xF << 4 * (gpio % 8);
    return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
    gpio_acknowledge_irq(gpio, events);
}

Page 101

#include <stdio.h>
#include "pico/stdlib.h"

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    printf("Press Button\n");
    sleep_ms(20000);
    if (gpio_get(22))
    {
        printf("Button Pressed\n");
    }
    else
    {
        printf("Button Not Pressed\n");
    }
}

Page 101

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/structs/iobank0.h"

uint32_t gpio_get_events(uint gpio)
{
    int32_t mask = 0xF << 4 * (gpio % 8);
    return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
    gpio_acknowledge_irq(gpio, events);
}

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    printf("Press Button\n");
    gpio_clear_events(22, GPIO_IRQ_EDGE_RISE);
    sleep_ms(20000);
    int32_t event = gpio_get_events(22);
    gpio_clear_events(22, GPIO_IRQ_EDGE_RISE);
    if (event & GPIO_IRQ_EDGE_RISE)
    {
        printf("Button Pressed\n");
    }
    else
    {
        printf("Button Not Pressed\n");
    }
}

Page 103

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/structs/iobank0.h"

uint32_t gpio_get_events(uint gpio)
{
    int32_t mask = 0xF << 4 * (gpio % 8);
    return (iobank0_hw->intr[gpio / 8] & mask) >> 4 * (gpio % 8);
}
void gpio_clear_events(uint gpio, uint32_t events)
{
    gpio_acknowledge_irq(gpio, events);
}

int main()
{
    uint64_t t;

    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    while (true)
    {
        gpio_clear_events(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
        while (!(gpio_get_events(22) & GPIO_IRQ_EDGE_RISE))
        {
        };
        t = time_us_64();
        gpio_clear_events(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL);
        while (!(gpio_get_events(22) & GPIO_IRQ_EDGE_FALL))
        {
        };
        t = (uint64_t)(time_us_64() - t);
        printf("%llu\n", t);
        sleep_ms(1000);
    }
}

Page 105

#include <stdio.h>
#include "pico/stdlib.h"

static uint64_t t;
void MyIRQHandler(uint gpio, uint32_t events)
{
    t = time_us_64() - t;
    printf("GPIO %d %X %d \n", gpio, events, t);
}

int main()
{
    stdio_init_all();
    gpio_set_function(22, GPIO_FUNC_SIO);
    gpio_set_dir(22, false);
    gpio_pull_down(22);

    gpio_set_irq_enabled_with_callback(22, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &MyIRQHandler);
    while (1)
    {
    };
    return 0;
}

Page 122  remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;

    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

int main()
{
    gpio_set_function(22, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(22);
    uint chan = pwm_gpio_to_channel(22);
    pwm_set_freq_duty(slice_num, chan, 50, 75);
    pwm_set_enabled(slice_num, true);
    return 0;
}

Page 124 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num,uint chan,
                                         uint32_t f, int d)
{
 uint32_t clock = 125000000;
 uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
 if (divider16 / 16 == 0)
 divider16 = 16;
 uint32_t wrap = clock * 16 / divider16 / f - 1;
 pwm_set_clkdiv_int_frac(slice_num, divider16/16, divider16 & 0xF);
 pwm_set_wrap(slice_num, wrap);
 pwm_set_chan_level(slice_num, chan, wrap * d / 100);
 return wrap;
}
uint32_t pwm_get_wrap(uint slice_num){
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);
    gpio_set_function(21, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);
    uint chan20 = pwm_gpio_to_channel(20);
    uint chan21 = pwm_gpio_to_channel(21);
    uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 75);
    pwm_set_duty(slice_num, chan21, 25);

    pwm_set_enabled(slice_num, true);

    return 0;
}

Page 126 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan,
                           uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);

    uint slice_num = pwm_gpio_to_slice_num(20);
    uint chan20 = pwm_gpio_to_channel(20);

    uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 50);

    pwm_set_enabled(slice_num, true);
    while (true)
    {
        pwm_set_duty(slice_num, chan20, 25);
        pwm_set_duty(slice_num, chan20, 50);
    }
    return 0;
}

Page 122 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan,
                           uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);
    uint chan20 = pwm_gpio_to_channel(20);
    uint wrap = pwm_set_freq_duty(slice_num, chan20, 50, 50);
    pwm_set_enabled(slice_num, true);
    while (true)
    {
        pwm_set_duty(slice_num, chan20, 25);
        while (pwm_get_counter(slice_num))
        {
        };
        pwm_set_duty(slice_num, chan20, 50);
        while (pwm_get_counter(slice_num))
        {
        };
    }
    return 0;
}

Page 129  remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}
uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

uint slice_num;
uint chan20;
uint state = 0;

void MyIRQHandler()
{
    pwm_clear_irq(slice_num);
    if (state)
    {
        pwm_set_duty(slice_num, chan20, 25);
    }
    else
    {
        pwm_set_duty(slice_num, chan20, 50);
    }
    state = ~state;
}

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);

    slice_num = pwm_gpio_to_slice_num(20);
    chan20 = pwm_gpio_to_channel(20);

    pwm_clear_irq(slice_num);
    pwm_set_irq_enabled(slice_num, true);
    irq_set_exclusive_handler(PWM_IRQ_WRAP, MyIRQHandler);
    irq_set_enabled(PWM_IRQ_WRAP, true);

    uint wrap = pwm_set_freq_duty(slice_num, chan20, 100000, 25);
    pwm_set_enabled(slice_num, true);
    while (true)
    {
    }
    return 0;
}

Page 131  remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"
#include "hardware/irq.h"
#include "math.h"

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}
uint slice_num;
uint chan20;
uint state = 0;
uint8_t wave[256];

void MyIRQHandler()
{
    pwm_clear_irq(slice_num);
    pwm_set_duty(slice_num, chan20, wave[state]);
    state = (state + 1) % 256;
}

int main()
{

    for (int i = 0; i < 256; i++)
    {
        wave[i] = (uint8_t)((128.0 + sinf((float)i * 2.0 * 3.14159 / 256.0) * 128.0) * 100.0 / 256.0);
    }

    gpio_set_function(22, GPIO_FUNC_PWM);

    slice_num = pwm_gpio_to_slice_num(22);
    uint chan22 = pwm_gpio_to_channel(22);

    pwm_clear_irq(slice_num);
    pwm_set_irq_enabled(slice_num, true);
    irq_set_exclusive_handler(PWM_IRQ_WRAP, MyIRQHandler);
    irq_set_enabled(PWM_IRQ_WRAP, true);

    pwm_set_clkdiv_int_frac(slice_num, 1, 0);
    pwm_set_wrap(slice_num, 255);

    pwm_set_enabled(slice_num, true);
    while (true)
    {
    }
    return 0;
}

Page 134 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(22, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(22);

    uint chan22 = pwm_gpio_to_channel(22);
    pwm_set_freq_duty(slice_num, chan22, 281, 50);

    pwm_set_enabled(slice_num, true);
}

Page 134 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(25, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(25);
    uint chan = pwm_gpio_to_channel(25);
    pwm_set_freq_duty(slice_num, chan, 2000, 0);
    pwm_set_enabled(slice_num, true);

    while (true)
    {
        for (int d = 0; d <= 100; d++)
        {
            pwm_set_duty(slice_num, chan, d);
            sleep_ms(50);
        }
    }
}

Page 136 remember to add hardware_pwm to the CMakeLists.txt file

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

int main()
{
    gpio_set_function(25, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(25);
    uint chan = pwm_gpio_to_channel(25);

    pwm_set_freq_duty(slice_num, chan, 2000, 0);

    pwm_set_enabled(slice_num, true);
    int d = 0;
    while (true)
    {
        for (int b = 0; b <= 100; b++)
        {
            d = (b * b * b) / 10000;
            pwm_set_duty(slice_num, chan, d);
            sleep_ms(50);
        }
    }
}

Page 138 remember to add hardware_pwm to the CMakeLists.txt file 

#include "pico/stdlib.h"
#include "hardware/pwm.h"

int main()
{
    gpio_set_function(20, GPIO_FUNC_PWM);
    gpio_set_function(21, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);

    uint chanA = pwm_gpio_to_channel(20);
    uint chanB = pwm_gpio_to_channel(21);
    pwm_set_clkdiv_int_frac(slice_num, 2, 0);
    pwm_set_wrap(slice_num, 127);
    pwm_set_chan_level(slice_num, chanA, 63);
    pwm_set_clkdiv_mode(slice_num, PWM_DIV_B_RISING);
    pwm_set_enabled(slice_num, true);
}

Page 140 remember to add hardware_pwm to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"
int main()
{
    stdio_init_all();
    gpio_set_function(20, GPIO_FUNC_PWM);
    gpio_set_function(21, GPIO_FUNC_PWM);
    uint slice_num = pwm_gpio_to_slice_num(20);

    uint chanA = pwm_gpio_to_channel(20);
    uint chanB = pwm_gpio_to_channel(21);

    pwm_set_clkdiv_int_frac(slice_num, 20, 0);
    int maxcount = 125000000 * 10 / 20 / 1000;

    pwm_set_wrap(slice_num, 65535);
    pwm_set_chan_level(slice_num, chanA, 100);
    pwm_set_clkdiv_mode(slice_num, PWM_DIV_B_HIGH);

    while (true)
    {
        pwm_set_enabled(slice_num, true);
        sleep_ms(10);
        pwm_set_enabled(slice_num, false);
        uint16_t count = pwm_get_counter(slice_num);
        pwm_set_counter(slice_num, 0);
        printf("count= %u  duty cycle=%d %%\n",
               count, (int)count * 100 / maxcount);
        sleep_ms(1000);
    }
}

Page 29 remember to add hardware_pwm to the CMakeLists.txt file 

#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

typedef struct
{
    uint gpio;
    uint slice;
    uint chan;
    uint speed;
    uint freq;
    uint resolution;
    bool on;
} Motor;

void motorInit(Motor *m, uint gpio, uint freq)
{
    gpio_set_function(gpio, GPIO_FUNC_PWM);
    m->gpio = gpio;
    m->slice = pwm_gpio_to_slice_num(gpio);
    m->chan = pwm_gpio_to_channel(gpio);
    m->freq = freq;
    m->speed = 0;
    m->resolution = pwm_set_freq_duty(m->slice, m->chan, m->freq, m->speed);
    m->on = false;
}

void motorspeed(Motor *m, int s)
{
    pwm_set_duty(m->slice, m->chan, s);
    m->speed = s;
}
void motorOn(Motor *m)
{
    pwm_set_enabled(m->slice, true);
    m->on = true;
}

void motorOff(Motor *m)
{
    pwm_set_enabled(m->slice, false);
    m->on = false;
}

int main()
{
    Motor mot1;
    motorInit(&mot1, 21, 2000);
    motorspeed(&mot1, 50);
    motorOn(&mot1);
    return 0;
}

 

Page 157 remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

typedef struct
{
    uint gpioForward;
    uint gpioBackward;
    uint slice;
    uint Fchan;
    uint Bchan;
    bool forward;
    uint speed;
    uint freq;
    uint resolution;
    bool on;
} BiMotor;

void BiMotorInit(BiMotor *m, uint gpioForward, uint gpioBackward, uint freq)
{
    gpio_set_function(gpioForward, GPIO_FUNC_PWM);
    m->gpioForward = gpioForward;
    m->slice = pwm_gpio_to_slice_num(gpioForward);
    m->Fchan = pwm_gpio_to_channel(gpioForward);

    gpio_set_function(gpioBackward, GPIO_FUNC_PWM);
    m->gpioBackward = gpioBackward;
    m->Bchan = pwm_gpio_to_channel(gpioBackward);

    m->freq = freq;
    m->speed = 0;
    m->forward = true;
    m->resolution = pwm_set_freq_duty(m->slice, m->Fchan, m->freq, 0);
    pwm_set_duty(m->slice, m->Bchan, 0);
    m->on = false;
}

void BiMotorspeed(BiMotor *m, int s, bool forward)
{
    if (forward)
    {
        pwm_set_duty(m->slice, m->Bchan, 0);
        pwm_set_duty(m->slice, m->Fchan, s);
        m->forward = true;
    }
    else
    {
        pwm_set_duty(m->slice, m->Fchan, 0);
        pwm_set_duty(m->slice, m->Bchan, s);
        m->forward = true;
    }
    m->speed = s;
}

void BiMotorOn(BiMotor *m)
{
    pwm_set_enabled(m->slice, true);
    m->on = true;
}

void BiMotorOff(BiMotor *m)
{
    pwm_set_enabled(m->slice, false);
    m->on = false;
}

int main()
{
    BiMotor mot1;
    BiMotorInit(&mot1, 20, 21, 2000);

    BiMotorOn(&mot1);
    while (true)
    {
        BiMotorspeed(&mot1, 50, true);
        sleep_ms(2000);
        BiMotorspeed(&mot1, 25, false);
        sleep_ms(2000);
    }

    return 0;
}

Page 162 remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/pwm.h"

uint32_t pwm_set_freq_duty(uint slice_num, uint chan, uint32_t f, int d)
{
    uint32_t clock = 125000000;
    uint32_t divider16 = clock / f / 4096 + (clock % (f * 4096) != 0);
    if (divider16 / 16 == 0)
        divider16 = 16;
    uint32_t wrap = clock * 16 / divider16 / f - 1;
    pwm_set_clkdiv_int_frac(slice_num, divider16 / 16, divider16 & 0xF);
    pwm_set_wrap(slice_num, wrap);
    pwm_set_chan_level(slice_num, chan, wrap * d / 100);
    return wrap;
}

uint32_t pwm_get_wrap(uint slice_num)
{
    valid_params_if(PWM, slice_num >= 0 && slice_num < NUM_PWM_SLICES);
    return pwm_hw->slice[slice_num].top;
}

void pwm_set_duty(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 100);
}

void pwm_set_dutyH(uint slice_num, uint chan, int d)
{
    pwm_set_chan_level(slice_num, chan, pwm_get_wrap(slice_num) * d / 10000);
}

typedef struct
{
    uint gpio;
    uint slice;
    uint chan;
    uint speed;
    uint resolution;
    bool on;
    bool invert;
} Servo;

void ServoInit(Servo *s, uint gpio, bool invert)
{
    gpio_set_function(gpio, GPIO_FUNC_PWM);
    s->gpio = gpio;
    s->slice = pwm_gpio_to_slice_num(gpio);
    s->chan = pwm_gpio_to_channel(gpio);

    pwm_set_enabled(s->slice, false);
    s->on = false;
    s->speed = 0;
    s->resolution = pwm_set_freq_duty(s->slice, s->chan, 50, 0);
    pwm_set_dutyH(s->slice, s->chan, 250);
    if (s->chan)
    {
        pwm_set_output_polarity(s->slice, false, invert);
    }
    else
    {
        pwm_set_output_polarity(s->slice, invert, false);
    }
    s->invert = invert;
}

void ServoOn(Servo *s)
{
    pwm_set_enabled(s->slice, true);
    s->on = true;
}

void ServoOff(Servo *s)
{
    pwm_set_enabled(s->slice, false);
    s->on = false;
}
void ServoPosition(Servo *s, uint p)
{
    pwm_set_dutyH(s->slice, s->chan, p * 10 + 250);
}

int main()
{
    Servo s1;
    ServoInit(&s1, 20, false);

    ServoOn(&s1);
    while (true)
    {
        ServoPosition(&s1, 0);
        sleep_ms(500);
        ServoPosition(&s1, 100);
        sleep_ms(500);
    }

    return 0;
}

Page 173 remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"

typedef struct
{
    uint gpio;
    uint speed;
    bool forward;
    uint32_t gpiomask;
    uint phase;
} StepperBi;

uint32_t stepTable[8] = (uint32_t[8]){0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9};
/*
    {1, 0, 0, 0},
    {1, 1, 0, 0},
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 0, 0, 1},
    {1, 0, 0, 1}
*/
void StepperBiInit(StepperBi *s, uint gpio)
{
    s->gpio = gpio;

    for (int i = 0; i < 4; i++)
    {
        gpio_set_function((s->gpio) + i, GPIO_FUNC_SIO);
        gpio_set_dir((s->gpio) + i, true);
    }
    s->gpiomask = 0x0F << gpio;
    volatile uint32_t mask = stepTable[0] << gpio;
    gpio_put_masked(s->gpiomask, mask);
    s->phase = 0;
    s->speed = 0;
    s->forward = true;
}

void setPhase(StepperBi *s, uint p)
{
    uint32_t mask = stepTable[p] << (s->gpio);
    gpio_put_masked(s->gpiomask, mask);
}

void stepForward(StepperBi *s)
{
    s->phase = (s->phase + 1) % 8;
    setPhase(s, s->phase);
}

void stepReverse(StepperBi *s)
{
    s->phase = (s->phase - 1) % 8;
    setPhase(s, s->phase);
}

void rotate(StepperBi *s, bool dir, int speed)
{
    s->forward = dir;
    s->speed = speed;
}

int main()
{
    stdio_init_all();
    StepperBi s1;
    StepperBiInit(&s1, 18);
    while (true)
    {
        stepForward(&s1);
        sleep_ms(1);
    }
    return 0;
}

Page 178 remember to add hardware_pwm to the CMakeLists.txt file 

 
#include <stdio.h>
#include "pico/stdlib.h"

typedef struct
{
    uint gpio;
    uint speed;
    bool forward;
    uint32_t gpiomask;
    uint phase;
} StepperBi;

uint32_t stepTable[8] = (uint32_t[8]){0x8, 0xC, 0x4, 0x6, 0x2, 0x3, 0x1, 0x9};
/*
    {1, 0, 0, 0},
    {1, 1, 0, 0},
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 0, 0, 1},
    {1, 0, 0, 1}
*/
void StepperBiInit(StepperBi *s, uint gpio)
{
    s->gpio = gpio;

    for (int i = 0; i < 4; i++)
    {
        gpio_set_function((s->gpio) + i, GPIO_FUNC_SIO);
        gpio_set_dir((s->gpio) + i, true);
    }
    s->gpiomask = 0x0F << gpio;
    volatile uint32_t mask = stepTable[0] << gpio;
    gpio_put_masked(s->gpiomask, mask);
    s->phase = 0;
    s->speed = 0;
    s->forward = true;
}

void setPhase(StepperBi *s, uint p)
{
    uint32_t mask = stepTable[p] << (s->gpio);
    gpio_put_masked(s->gpiomask, mask);
}

void stepForward(StepperBi *s)
{
    s->phase = (s->phase + 1) % 8;
    setPhase(s, s->phase);
}

void stepReverse(StepperBi *s)
{
    s->phase = (s->phase - 1) % 8;
    setPhase(s, s->phase);
}

bool step(struct repeating_timer *t)
{
    StepperBi *s = (StepperBi *)(t->user_data);
    if (s->forward)
    {
        stepForward(s);
    }
    else
    {
        stepReverse(s);
    }
    return true;
}
struct repeating_timer timer;

void rotate(StepperBi *s, bool dir, int speed)
{
    cancel_repeating_timer(&timer);
    s->forward = dir;
    if (speed == 0)
    {
        s->speed = 0;
        return;
    }
    s->speed = 1000 * 1000 / (4 * speed);
    add_repeating_timer_us(s->speed, step, s, &timer);
}

int main()
{
    static StepperBi s1;
    StepperBiInit(&s1, 18);
    rotate(&s1, true, 250);
    while (true)
    {
        rotate(&s1, true, 250);
        sleep_ms(100);
        rotate(&s1, true, 00);
        sleep_ms(100);
    }
    return 0;
}

Page 189 remember to add hardware_spi to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"

int main()
{
    stdio_init_all();
    spi_init(spi0, 500 * 1000);
    gpio_set_function(4, GPIO_FUNC_SPI);
    gpio_set_function(6, GPIO_FUNC_SPI);
    gpio_set_function(7, GPIO_FUNC_SPI);
    spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
    uint16_t wBuff[1] = {0xAA};
    uint16_t rBuff[1];

    int n = spi_write16_read16_blocking(spi0, wBuff, rBuff, 1);
    spi_deinit(spi0);
    printf(" %X %X %d ", wBuff[0], rBuff[0], n);
}

Page 197 remember to add hardware_spi to the CMakeLists.txt file 

#include <stdio.h>

#include "pico/stdlib.h"
#include "hardware/spi.h"

int main()
{
    stdio_init_all();

    spi_init(spi0, 500 * 1000);
    spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);

    gpio_set_function(16, GPIO_FUNC_SPI);
    gpio_set_function(18, GPIO_FUNC_SPI);
    gpio_set_function(19, GPIO_FUNC_SPI);

    gpio_init(17);
    gpio_set_dir(17, GPIO_OUT);
    gpio_put(17, 1);
    sleep_ms(1);
    uint8_t wBuff[1] = {0xD0};
    uint8_t rBuff[8];

    gpio_put(17, 0);
    sleep_us(1);
    spi_write_blocking(spi0, wBuff, 1);
    spi_read_blocking(spi0, 0, rBuff, 1);
    sleep_us(1);
    gpio_put(17, 1);
    printf("Chip ID is 0x%x\n", rBuff[0]);
    gpio_put(17, 0);
    sleep_us(1);
    wBuff[0] = 0xF2;
    wBuff[1] = 0x1;
    spi_write_blocking(spi0, wBuff, 2);
    wBuff[0] = 0xF4;
    wBuff[1] = 0x27;
    spi_write_blocking(spi0, wBuff, 2);
    gpio_put(17, 1);
    sleep_us(1);

    wBuff[0] = 0xF7;
    gpio_put(17, 0);
    sleep_us(1);
    spi_write_blocking(spi0, wBuff, 1);

    spi_read_blocking(spi0, 0, rBuff, 8);
    sleep_us(1);
    gpio_put(17, 1);

    uint32_t pressure = ((uint32_t)rBuff[0] << 12) | ((uint32_t)rBuff[1] << 4) | (rBuff[2] >> 4);
    uint32_t temperature = ((uint32_t)rBuff[3] << 12) | ((uint32_t)rBuff[4] << 4) | (rBuff[5] >> 4);
    uint32_t humidity = (uint32_t)rBuff[6] << 8 | rBuff[7];

    printf("Humidity = %d\n", humidity);
    printf("Pressure = %d\n", pressure);
    printf("Temp. = %d\n", temperature);
}

Page 203 remember to add hardware_adc to the CMakeLists.txt file 

#include
#include "pico/stdlib.h"
#include "hardware/adc.h"
int main()
{
stdio_init_all();
adc_init();
adc_gpio_init(26);
adc_gpio_init(27);

while (1)
{
const float conversion_factor = 3.3f / (1 << 12);
adc_select_input(0);
uint16_t result = adc_read();
printf("Raw value 0: 0x%03x, voltage: %f V\n",
result, result * conversion_factor);
adc_select_input(1);
result = adc_read();
printf("Raw value 1: 0x%03x, voltage: %f V\n",
result, result * conversion_factor);
sleep_ms(500);
}
}

Page 205 remember to add hardware_adc to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/adc.h"

int main()
{
    stdio_init_all();

    adc_init();
    adc_gpio_init(26);
    adc_gpio_init(27);
    adc_set_round_robin(0x03);
    adc_fifo_setup(true, false, 0, false, false);
    adc_run(true);
    const float conversion_factor = 3.3f / (1 << 12);
    while (1)
    {
        uint16_t result = adc_fifo_get();
        printf("Raw value 0: 0x%03x, voltage: %f V\n", result, result * conversion_factor);
        int level = adc_fifo_get_level();
        printf("level: %d \n", level);
    }
}

Page 211 remember to add hardware_spi to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/spi.h"

int main()
{
    stdio_init_all();
    spi_init(spi0, 500 * 1000);
    spi_set_format(spi0, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
    gpio_set_function(16, GPIO_FUNC_SPI);
    gpio_set_function(18, GPIO_FUNC_SPI);
    gpio_set_function(19, GPIO_FUNC_SPI);
    gpio_init(17);
    gpio_set_dir(17, GPIO_OUT);
    gpio_put(17, 1);
    sleep_ms(1);
    uint16_t wBuff[3] = {0x01, 0x80, 0x00};
    uint16_t rBuff[3];
    gpio_put(17, 0);
    int n = spi_write16_read16_blocking(spi0, wBuff, rBuff, 3);
    sleep_us(1);
    gpio_put(17, 1);
    int data = ((int)rBuff[1] & 0x03) << 8 | (int)rBuff[2];
    float volts = (float)data * 3.3f / 1023.0f;
    printf("%f V\n", volts);
}

Page 228 remember to add hardware_i2c to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"

int main()
{
    stdio_init_all();

    i2c_init(i2c0, 100 * 1000);

    gpio_set_function(4, GPIO_FUNC_I2C);
    gpio_set_function(5, GPIO_FUNC_I2C);
    uint8_t buf[] = {0xE7};

    i2c_write_blocking(i2c0, 0x40, buf, 1, false);
    i2c_read_blocking(i2c0, 0x40, buf, 1, false);
    printf("User Register = %X \r\n", buf[0]);
}

Page 230 remember to add hardware_i2c to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"

int main()
{
    stdio_init_all();

    i2c_init(i2c0, 100 * 1000);

    gpio_set_function(4, GPIO_FUNC_I2C);
    gpio_set_function(5, GPIO_FUNC_I2C);

    uint8_t buf[4] = {0xE3};
    i2c_write_blocking(i2c0, 0x40, buf, 1, true);
    i2c_read_blocking(i2c0, 0x40, buf, 3, false);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
};

Page 234 remember to add hardware_i2c to the CMakeLists.txt file 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/i2c.h"
uint8_t crcCheck(uint8_t msb, uint8_t lsb, uint8_t check)
{
    uint32_t data32 = ((uint32_t)msb << 16) | ((uint32_t)lsb << 8) |
                      (uint32_t)check;
    uint32_t divisor = 0x988000;
    for (int i = 0; i < 16; i++)
    {
        if (data32 & (uint32_t)1 << (23 - i))
            data32 ^= divisor;
        divisor >>= 1;
    };
    return (uint8_t)data32;
}
int main()
{
    stdio_init_all();

    i2c_init(i2c0, 100 * 1000);

    gpio_set_function(4, GPIO_FUNC_I2C);
    gpio_set_function(5, GPIO_FUNC_I2C);

    uint8_t buf[4] = {0xE3};
    i2c_write_blocking(i2c0, 0x40, buf, 1, true);
    i2c_read_blocking(i2c0, 0x40, buf, 3, false);
    uint8_t msb = buf[0];
    uint8_t lsb = buf[1];
    uint8_t check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    unsigned int data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    float temp = (float)(-46.85 + (175.72 * data16 / (float)65536));
    printf("Temperature %f C \n\r", temp);

    buf[0] = 0xF5;
    i2c_write_blocking(i2c0, 0x40, buf, 1, true);
    while (i2c_read_blocking(i2c0, 0x40, buf, 3, false) < 0)
    {
        sleep_ms(1);
    };

    msb = buf[0];
    lsb = buf[1];
    check = buf[2];
    printf("msb %d \n\r lsb %d \n\r checksum %d \n\r", msb, lsb, check);
    printf("crc = %d\n\r", crcCheck(msb, lsb, check));
    data16 = ((unsigned int)msb << 8) | (unsigned int)(lsb & 0xFC);
    float hum = -6 + (125.0 * (float)data16) / 65536;
    printf("Humidity %f %% \n\r", hum);
}

Page 240

.program squarewave
    set pindirs, 1   ; Set pin to output
again:
    set pins, 1      ; Drive pin high
    set pins, 0      ; Drive pin low
    jmp again        ; Set PC to label `again`

Page 241

cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
pico_sdk_init()

project(pioBlinky C CXX ASM)
add_executable(pio
 pio.c
)
pico_generate_pio_header(pio ${CMAKE_CURRENT_LIST_DIR}/sqwave.pio)

target_link_libraries(pio  pico_stdlib hardware_pio)
pico_add_extra_outputs(pio)

Page 189 remember to use the CMakeLists.txt file and the PIO program given earlier 

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{
    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);

    sm_config_set_set_pins(&c, 2, 1);
    pio_gpio_init(pio0, 2);

    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);
    return 0;
}

Page 247-248

PIO Program
.program squarewave
    set pindirs, 1  
    pull block
again:
    set pins, 1 
    mov x, osr
 loop1: 
     jmp x--,loop1
    set pins, 0 
    mov x, osr
 loop2:  
   jmp x--,loop2 
jmp again
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"

#include "sqwave.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);

    sm_config_set_set_pins(&c, 2, 1);
    pio_gpio_init(pio0, 2);

    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    pio_sm_put_blocking(pio0, sm, 0xFFFF);
    return 0;
}

Page 249-250

PIO Program

.program squarewave

    set pindirs, 3  
    pull block    
again:
    out pins,2
    jmp again 
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_set_pins(&c, 2, 2);
    sm_config_set_out_pins(&c, 2, 2);
    pio_gpio_init(pio0, 2);
    pio_gpio_init(pio0, 3);

    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    pio_sm_put_blocking(pio0, sm, 0xFEDCBA98);
    return 0;
}

Page 252

PIO Program

.program squarewave   
again:
  out pins,2
  jmp again 
C Program
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{
    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_set_pins(&c, 2, 2);
    sm_config_set_out_pins(&c, 2, 2);
    pio_gpio_init(pio0, 2);
    pio_gpio_init(pio0, 3);
    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 2, true);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    sm_config_set_out_shift(&c, true, true, 6);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);
    while (true)
    {
        pio_sm_put_blocking(pio0, sm, 0xFEDCBA98);
    }
    return 0;
}

Page  254

PIO Program
.program squarewave   
.side_set 1 opt
again:
  nop side 1
  jmp  again side 0 

C Program

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{
    uint offset = pio_add_program(pio0, &squarewave_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_sideset_pins(&c, 2);
    pio_gpio_init(pio0, 2);
    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, true);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    pio_sm_init(pio0, sm, offset, &c);

    pio_sm_set_enabled(pio0, sm, true);
    return 0;
}

Page 257

PIO Program
.program light  
again:
  in pins,1
  push block
  jmp  again  

C Program

#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "light.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &light_program);

    uint sm = pio_claim_unused_sm(pio0, true);
    pio_sm_config c = light_program_get_default_config(offset);

    sm_config_set_in_pins(&c, 2);
    pio_gpio_init(pio0, 2);

    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, false);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);

    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    gpio_init(25);
    gpio_set_dir(25, GPIO_OUT);
    while (true)
    {
        uint32_t flag = pio_sm_get_blocking(pio0, sm);
        if (flag == 0)
        {
            gpio_put(25, 0);
        }
        else
        {
            gpio_put(25, 1);
        }
    }

    return 0;
}

Page 259

PIO Program

.program squarewave  
again:
   wait 0 pin 0
   wait 1 pin 0
   set pins, 1  
   set pins, 0  
jmp  again
  
CProgram
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "sqwave.pio.h"

int main()
{

    uint offset = pio_add_program(pio0, &squarewave_program);
    uint sm = pio_claim_unused_sm(pio0, true);

    pio_sm_config c = squarewave_program_get_default_config(offset);
    sm_config_set_set_pins(&c, 3, 1);
    sm_config_set_in_pins(&c, 2);

    pio_gpio_init(pio0, 2);
    pio_gpio_init(pio0, 3);
    pio_sm_set_consecutive_pindirs(pio0, sm, 2, 1, false);
    pio_sm_set_consecutive_pindirs(pio0, sm, 3, 1, true);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);

    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);

    return 0;
}

Page 189

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int main()
{
    stdio_init_all();
    gpio_init(2);
    gpio_set_dir(2, GPIO_OUT);
    gpio_put(2, 1);
    sleep_ms(1);
    gpio_put(2, 0);
    sleep_ms(1);
    gpio_set_dir(2, GPIO_IN);
    return 0;
}

Page 267

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int main()
{
    stdio_init_all();
    gpio_init(2);
    gpio_set_dir(2, GPIO_OUT);
    gpio_put(2, 1);
    sleep_ms(1);
    gpio_put(2, 0);
    sleep_ms(1);
    gpio_set_dir(2, GPIO_IN);
    return 0;
}

Page 270 

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

inline static void WaitFallingEdge(uint gpio)
{
    while (gpio_get(gpio) == 1)
    {
    };
    while (gpio_get(gpio) == 0)
    {
    };
}

uint32_t getData(uint gpio)
{
    uint32_t t2;
    uint32_t data = 0;
    uint32_t t1 = time_us_32();
    for (int i = 0; i < 32; i++)
    {
        WaitFallingEdge(2);
        t2 = time_us_32();
        data = data << 1;
        data = data | ((t2 - t1) > 100);
        t1 = t2;
    }
    return data;
}
uint8_t getCheck(uint gpio)
{
    uint8_t checksum = 0;
    uint32_t t2;
    uint32_t t1 = time_us_32();
    for (int i = 0; i < 8; i++)
    {
        WaitFallingEdge(2);
        t2 = time_us_32();
        checksum = checksum << 1;
        checksum = checksum | (t2 - t1) > 100;
        t1 = t2;
    }
    return checksum;
}

void dhtInitalize(uint gpio)
{
    gpio_init(gpio);
    gpio_set_dir(gpio, GPIO_OUT);
    gpio_put(gpio, 1);
    sleep_ms(1);
    gpio_put(gpio, 0);
    sleep_ms(1);
    gpio_set_dir(gpio, GPIO_IN);
    for (int i = 0; i < 2; i++)
    {
        WaitFallingEdge(gpio);
    }
}

typedef struct
{
    float temperature;
    float humidity;
    bool error;
} dhtData;

void dhtread(uint gpio, dhtData *reading)
{
    dhtInitalize(gpio);
    uint32_t data = getData(gpio);
    uint8_t checksum = getCheck(gpio);
    uint8_t byte1 = (data >> 24 & 0xFF);
    uint8_t byte2 = (data >> 16 & 0xFF);
    uint8_t byte3 = (data >> 8 & 0xFF);
    uint8_t byte4 = (data & 0xFF);

    reading->error = (checksum != ((byte1 + byte2 + byte3 + byte4) & 0xFF));
    reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;

    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        reading->temperature = -reading->temperature;
}

int main()
{
    stdio_init_all();
    printf("data^^^^^\n");
    dhtData reading;
    dhtread(2, &reading);
    printf("Humidity= %f %\n", reading.humidity);
    printf("Temperature= %f C\n", reading.temperature);
    return 0;
}

Page 275

PIO Program

.program dht
    set pins, 1 
    set pindirs, 1    
again:
  pull block
  set pins, 0
mov x, osr
loop1: 
    jmp x--,loop1
set pindirs, 0 
wait 1 pin 0
wait 0 pin 0
wait 1 pin 0
wait 0 pin 0

    set y,31
bits:
    wait 1 pin 0
    set x, 0
loop2:
        jmp x--,continue
continue: jmp pin,loop2 
        in x,4  
    jmp y--,bits

    set y,7
check:
    wait 1 pin 0
    set x, 0
loop3:
        jmp x--,continue2
continue2: jmp pin,loop3
        in x,4  
    jmp y--,check
jmp again

C Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"

#include "DHT.pio.h"
uint dhtInitalize(PIO pio, int gpio)
{

    uint offset = pio_add_program(pio, &dht_program);

    uint sm = pio_claim_unused_sm(pio, true);
    pio_gpio_init(pio, gpio);
    pio_sm_config c = dht_program_get_default_config(offset);
    sm_config_set_clkdiv_int_frac(&c, 128, 0);

    sm_config_set_set_pins(&c, gpio, 1);
    sm_config_set_in_pins(&c, gpio);

    sm_config_set_jmp_pin(&c, gpio);
    sm_config_set_in_shift(&c, true, true, 32);
    pio_sm_init(pio0, sm, offset, &c);

    pio_sm_set_enabled(pio0, sm, true);
    return sm;
}

uint8_t getByte(PIO pio, uint sm)
{
    uint32_t count = pio_sm_get_blocking(pio0, sm);
    uint8_t byte = 0;
    for (int i = 0; i < 8; i++)
    {
        byte = byte << 1;
        if (((count >> i * 4) & 0x0F) > 8)
        {
            byte = byte | 1;
        }
    }
    return byte;
}

typedef struct
{
    float temperature;
    float humidity;
    bool error;
} dhtData;

void dhtread(PIO pio, uint sm, dhtData *reading)
{

    pio_sm_put_blocking(pio, sm, 1000);

    uint8_t byte1 = getByte(pio, sm);
    uint8_t byte2 = getByte(pio, sm);
    uint8_t byte3 = getByte(pio, sm);
    uint8_t byte4 = getByte(pio, sm);

    uint8_t checksum = getByte(pio, sm);

    reading->error = (checksum == (byte1 + byte2 + byte3 + byte4) & 0xFF);
    reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;

    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        reading->temperature = -reading->temperature;
}

int main()
{
    stdio_init_all();
    uint sm = dhtInitalize(pio0, 2);
    dhtData reading;
    dhtread(pio0, sm, &reading);
    printf("Humidity= %f %\n", reading.humidity);
    printf("Temperature= %f C\n", reading.temperature);
    return 0;
}

Page 280

PIO Program
.program dht
 set pins, 1 
 set pindirs, 1 
again:
 pull block
 set pins, 0
mov x, osr
loop1: 
 jmp x--,loop1
set pindirs, 0 
wait 1 pin 0
wait 0 pin 0
wait 1 pin 0
wait 0 pin 0

set y,31
bits:
 wait 1 pin 0 [25]
 in pins,1 
 wait 0 pin 0
 jmp y--,bits

 set y,7
check:
wait 1 pin 0 [25]
 in pins,1 
 wait 0 pin 0 
 jmp y--,check
push block
jmp again

C Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "hardware/pio.h"

#include "DHT.pio.h"
uint dhtInitalize(PIO pio, int gpio)
{

    uint offset = pio_add_program(pio, &dht_program);

    uint sm = pio_claim_unused_sm(pio, true);
    pio_gpio_init(pio, gpio);

    pio_sm_config c = dht_program_get_default_config(offset);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    sm_config_set_set_pins(&c, gpio, 1);
    sm_config_set_in_pins(&c, gpio);
    sm_config_set_in_shift(&c, false, true, 32);
    pio_sm_init(pio0, sm, offset, &c);

    pio_sm_set_enabled(pio0, sm, true);
    return sm;
}

typedef struct
{
    float temperature;
    float humidity;
    bool error;
} dhtData;

void dhtread(PIO pio, uint sm, dhtData *reading)
{
    pio_sm_put_blocking(pio, sm, 500);

    uint32_t data = pio_sm_get_blocking(pio0, sm);
    uint8_t byte1 = (data >> 24 & 0xFF);
    uint8_t byte2 = (data >> 16 & 0xFF);
    uint8_t byte3 = (data >> 8 & 0xFF);
    uint8_t byte4 = (data & 0xFF);
    uint8_t checksum = pio_sm_get_blocking(pio0, sm) & 0xFF;

    reading->error = (checksum != ((byte1 + byte2 + byte3 + byte4) & 0xFF));
    reading->humidity = (float)((byte1 << 8) | byte2) / 10.0;

    int neg = byte3 & 0x80;
    byte3 = byte3 & 0x7F;
    reading->temperature = (float)(byte3 << 8 | byte4) / 10.0;
    if (neg > 0)
        reading->temperature = -reading->temperature;
}

int main()
{
    stdio_init_all();
    uint sm = dhtInitalize(pio0, 2);
    dhtData reading;
    dhtread(pio0, sm, &reading);
    printf("Humidity= %f %\n", reading.humidity);
    printf("Temperature= %f C\n", reading.temperature);
    return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)


project(dht C CXX ASM)
pico_sdk_init()
add_executable(dht
 DHT.c
)
pico_generate_pio_header(dht ${CMAKE_CURRENT_LIST_DIR}/DHT.pio)
target_link_libraries(dht  pico_stdlib hardware_pio)
pico_add_extra_outputs(dht)

Page 300

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int presence(uint8_t pin)
{
    gpio_set_dir(2, GPIO_OUT);
    gpio_put(pin, 1);
    sleep_ms(1);
    gpio_put(pin, 0);
    sleep_us(480);
    gpio_set_dir(pin, GPIO_IN);
    sleep_us(70);
    int b = gpio_get(pin);
    sleep_us(410);
    return b;
}

void writeBit(uint8_t pin, int b)
{
    int delay1, delay2;
    if (b == 1)
    {
        delay1 = 6;
        delay2 = 64;
    }
    else
    {
        delay1 = 60;
        delay2 = 10;
    }
    gpio_set_dir(pin, GPIO_OUT);
    gpio_put(pin, 0);
    sleep_us(delay1);
    gpio_set_dir(pin, GPIO_IN);
    sleep_us(delay2);
}

void writeByte(uint8_t pin, int byte)
{
    for (int i = 0; i < 8; i++)
    {
        if (byte & 1)
        {
            writeBit(pin, 1);
        }
        else
        {
            writeBit(pin, 0);
        }
        byte = byte >> 1;
    }
}

uint8_t readBit(uint8_t pin)
{
    gpio_set_dir(pin, GPIO_OUT);
    gpio_put(pin, 0);
    sleep_us(8);
    gpio_set_dir(pin, GPIO_IN);
    sleep_us(2);
    uint8_t b = gpio_get(pin);
    sleep_us(60);
    return b;
}

int readByte(uint8_t pin)
{
    int byte = 0;
    int i;
    for (i = 0; i < 8; i++)
    {
        byte = byte | readBit(pin) << i;
    };
    return byte;
}

int convert(uint8_t pin)
{
    writeByte(pin, 0x44);
    int i;
    for (i = 0; i < 500; i++)
    {
        sleep_ms(10);
        if (readBit(pin) == 1)
            break;
    }
    return i;
}

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;

            databyte >>= 1;
        }
    }

    return crc;
}

float getTemperature(uint8_t pin)
{
    if (presence(pin) == 1)
        return -1000;
    writeByte(pin, 0xCC);
    if (convert(pin) == 500)
        return -3000;
    presence(pin);
    writeByte(pin, 0xCC);
    writeByte(pin, 0xBE);
    int i;
    uint8_t data[9];
    for (i = 0; i < 9; i++)
    {
        data[i] = readByte(pin);
    }
    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    float temp = (float)temp1 / 16;
    return temp;
}

int main()
{
    stdio_init_all();
    gpio_init(2);

    if (presence(2) == 1)
    {
        printf("No device \n");
    }
    float t;
    for (;;)
    {
        do
        {
            t = getTemperature(2);
        } while (t < -999);
        printf("%f\r\n", t);
        sleep_ms(500);
    };

    return 0;
}

Page 309

PIO Program

.program DS1820 
.wrap_target
again:
  pull block
  mov x, osr
  jmp !x, read

write:  set pindirs, 1 
  set pins, 0  
loop1: 
    jmp x--,loop1
set pindirs, 0 [31]
wait 1 pin 0 [31]

  pull block
  mov x, osr
bytes1:
   pull block
  set y, 7    
  set pindirs, 1 
bit1:
  set pins, 0 [1]
  out pins,1 [31]
    set pins, 1 [20]
   jmp y--,bit1
jmp x--,bytes1

set pindirs, 0 [31]
jmp again

read:
  pull block
  mov x, osr
bytes2:
  set y, 7
bit2:
  set pindirs, 1 
  set pins, 0 [1]  
  set pindirs, 0 [5]
  in pins,1 [10]   
jmp y--,bit2
jmp x--,bytes2
.wrap

C Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include "DS1820.pio.h"

uint8_t crc8(uint8_t *data, uint8_t len)
{
    uint8_t i;
    uint8_t j;
    uint8_t temp;
    uint8_t databyte;
    uint8_t crc = 0;
    for (i = 0; i < len; i++)
    {
        databyte = data[i];
        for (j = 0; j < 8; j++)
        {
            temp = (crc ^ databyte) & 0x01;
            crc >>= 1;
            if (temp)
                crc ^= 0x8C;

            databyte >>= 1;
        }
    }

    return crc;
}

void writeBytes(PIO pio, uint sm, uint8_t bytes[], int len)
{
    pio_sm_put_blocking(pio, sm, 250);
    pio_sm_put_blocking(pio, sm, len - 1);
    for (int i = 0; i < len; i++)
    {
        pio_sm_put_blocking(pio, sm, bytes[i]);
    }
}
void readBytes(PIO pio, uint sm, uint8_t bytes[], int len)
{
    pio_sm_put_blocking(pio, sm, 0);
    pio_sm_put_blocking(pio, sm, len - 1);
    for (int i = 0; i < len; i++)
    {
        bytes[i] = pio_sm_get_blocking(pio, sm) >> 24;
    }
}

float getTemperature(PIO pio, uint sm)
{
    writeBytes(pio, sm, (uint8_t[]){0xCC, 0x44}, 2);
    sleep_ms(1000);
    writeBytes(pio, sm, (uint8_t[]){0xCC, 0xBE}, 2);

    uint8_t data[9];
    readBytes(pio, sm, data, 9);

    uint8_t crc = crc8(data, 9);
    if (crc != 0)
        return -2000;
    int t1 = data[0];
    int t2 = data[1];
    int16_t temp1 = (t2 << 8 | t1);
    volatile float temp = (float)temp1 / 16;
    return temp;
}

uint DS18Initalize(PIO pio, int gpio)
{

    uint offset = pio_add_program(pio, &DS1820_program);

    uint sm = pio_claim_unused_sm(pio, true);
    pio_gpio_init(pio, gpio);

    pio_sm_config c = DS1820_program_get_default_config(offset);
    sm_config_set_clkdiv_int_frac(&c, 255, 0);
    sm_config_set_set_pins(&c, gpio, 1);
    sm_config_set_out_pins(&c, gpio, 1);
    sm_config_set_in_pins(&c, gpio);
    sm_config_set_in_shift(&c, true, true, 8);
    pio_sm_init(pio0, sm, offset, &c);
    pio_sm_set_enabled(pio0, sm, true);
    return sm;
}

int main()
{
    stdio_init_all();

    uint sm = DS18Initalize(pio0, 2);

    float t;
    for (;;)
    {
        do
        {
            t = getTemperature(pio0, sm);
        } while (t < -999);
        printf("temperature %f\r\n", t);
        sleep_ms(500);
    };

    return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.13)

set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(ds18 C CXX ASM)
pico_sdk_init()
add_executable(ds18
 DS1820.c
)
pico_generate_pio_header(ds18 ${CMAKE_CURRENT_LIST_DIR}/DS1820.pio)
target_link_libraries(ds18  pico_stdlib hardware_gpio hardware_pio)
pico_add_extra_outputs(ds18)

Page 322

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"

int main()
{
    stdio_init_all();
    uart_init(uart1, 9600);
    gpio_set_function(4, GPIO_FUNC_UART);
    gpio_set_function(5, GPIO_FUNC_UART);
    uart_set_format(uart1, 8, 1, UART_PARITY_EVEN);
    uint8_t SendData[] = "Hello World";
    uint8_t RecData[20];
    uart_write_blocking(uart1, SendData, 11);
    uart_read_blocking(uart1, RecData, 11);
    RecData[11] = 0;
    printf("%s", RecData);
}

Page 334

#include "pico/stdlib.h"
#include "hardware/gpio.h"

#define Debug true
int initWiFi()
{
    uart_init(uart1, 115200);
    gpio_set_function(4, GPIO_FUNC_UART);
    gpio_set_function(5, GPIO_FUNC_UART);
    uart_set_format(uart1, 8, 1, UART_PARITY_NONE);
    sleep_ms(100);
    return 0;
}
int getBlock(uint8_t buf[], int len)
{
    int count = 0;
    while (count < len - 1)
    {
        if (uart_is_readable_within_us(uart1, 10000))
        {
            buf[count++] = uart_getc(uart1);
            if (Debug)
                uart_putc(uart0, buf[count - 1]);
        }
        else
        {
            break;
        }
    }
    buf[count] = 0;
    return count;
}

int ATWiFi(uint8_t buf[], int len)
{
    uint8_t SendData[] = "AT\r\n";
    uart_write_blocking(uart1, SendData, 4);
    return getBlock(buf, len);
}

int main()
{
    stdio_init_all();
    initWiFi();
    uint8_t buf[512];
    ATWiFi(buf, 512);
    sleep_ms(1000);
}

Page 347

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
#include <string.h>

#define Debug true
int initWiFi()
{
    uart_init(uart1, 115200);
    gpio_set_function(4, GPIO_FUNC_UART);
    gpio_set_function(5, GPIO_FUNC_UART);
    uart_set_format(uart1, 8, 1, UART_PARITY_NONE);

    uart_set_translate_crlf(uart0, true);
    sleep_ms(100);
    return 0;
}

int getBlock(uint8_t buf[], int len)
{
    int count = 0;
    while (count < len - 1)
    {
        if (uart_is_readable_within_us(uart1, 10000))
        {
            buf[count++] = uart_getc(uart1);
            if (Debug)
                uart_putc(uart0, buf[count - 1]);
        }
        else
        {
            break;
        }
    }
    buf[count] = 0;
    return count;
}

int ATWiFi(uint8_t buf[], int len)
{
    uint8_t SendData[] = "AT\r\n";
    uart_write_blocking(uart1, SendData, 4);
    return getBlock(buf, len);
}

int getVersionWiFi(uint8_t buf[], int len)
{
    uint8_t SendData[] = "AT+GMR\r\n";
    uart_write_blocking(uart1, SendData, 8);
    return getBlock(buf, len);
}

int resetWiFi(uint8_t buf[], int len)
{
    uint8_t SendData[] = "AT+RST\r\n";
    uart_write_blocking(uart1, SendData, 8);
    return getBlock(buf, len);
}

int setUARTWiFi(uint8_t buf[], int len)
{
    uint8_t SendData[] = "AT+UART_CUR=115200,8,1,0,0\r\n";
    uart_write_blocking(uart1, SendData, 28);
    return getBlock(buf, len);
}

int modeWiFi(uint8_t buf[], int len, int mode)
{
    uint8_t command[32];
    int count = snprintf(command, 32, "AT+CWMODE_CUR=%d\r\n", mode);
    uart_write_blocking(uart1, command, count);
    return getBlock(buf, len);
}

int getBlocks(uint8_t buf[], int len, int num, char target[])
{
    for (int i = 0; i < num; i++)
    {
        if (uart_is_readable_within_us(uart1, 1000 * 1000))
        {
            getBlock(buf, len);
            if (strstr(buf, target))
                return i;
        }
    }
    return -1;
}

int scanWiFi(uint8_t buf[], int len)
{
    uint8_t SendData[] = "AT+CWLAP\r\n";
    uart_write_blocking(uart1, SendData, 18);
    return getBlocks(buf, len, 20, "OK");
}

int connectWiFi(uint8_t buf[], int len, char ssid[], char pass[])
{
    uint8_t command[128];
    int count = snprintf(command, 128, "AT+CWJAP_CUR=\"%s\",\"%s\"\r\n", ssid, pass);
    uart_write_blocking(uart1, command, count);
    return getBlocks(buf, len, 20, "OK");
}

int getIPWiFi(uint8_t buf[], int len)
{
    uint8_t SendData[] = "AT+CIFSR\r\n";
    uart_write_blocking(uart1, SendData, 10);
    return getBlocks(buf, len, 20, "OK");
}

int getWebPageWiFi(uint8_t buf[], int len, char URL[], char page[])
{
    uint8_t command[128];
    int count = snprintf(command, 128, "AT+CIPSTART=\"TCP\",\"%s\",80\r\n", URL);
    uart_write_blocking(uart1, command, count);
    if (getBlocks(buf, len, 20, "OK") < 0)
        return -1;
    char http[150];
    sprintf(http, "GET %s HTTP/1.1\r\nHost:%s\r\n\r\n", page, URL);
    count = snprintf(command, 128, "AT+CIPSEND=%d\r\n", strlen(http));
    uart_write_blocking(uart1, command, count);
    if (getBlocks(buf, len, 20, ">") < 0)
        return -1;
    uart_write_blocking(uart1, http, strlen(http));
    return getBlocks(buf, len, 20, "</html>");
}

int startServerWiFi(uint8_t buf[], int len)
{
    char temp[256];
    char id[10];
    uart_write_blocking(uart1, "AT+CIPMUX=1\r\n", 13);
    if (getBlocks(buf, len, 10, "OK") < 0)
        return -1;
    uart_write_blocking(uart1, "AT+CIPSERVER=1,80\r\n", 19);
    if (getBlocks(buf, len, 10, "OK") < 0)
        return -1;

    for (;;)
    {
        if (getBlocks(buf, len, 1, "+IPD") < 0)
            continue;

        char *b = strstr(buf, "+IPD");
        b += 5;
        strncpy(temp, b, sizeof(temp));
        char *e = strstr(temp, ",");
        int d = e - temp;
        memset(id, '\0', sizeof(id));
        strncpy(id, temp, d);

        char data[] = "HTTP/1.0 200 OK\r\nServer: Pico\r\nContent-type: text/html\r\n\r\n<html><head><title>Temperature</title></head><body><p>{\"humidity\":81%,\"airtemperature\":23.5C}</p></body></html>\r\n";

        uint8_t command[128];
        int count = snprintf(command, 128, "AT+CIPSEND=%s,%d\r\n", id, strlen(data));
        uart_write_blocking(uart1, command, count);
        if (getBlocks(buf, len, 10, ">") < 0)
            return -1;

        uart_write_blocking(uart1, data, strlen(data));
        if (getBlocks(buf, len, 10, "OK") < 0)
            return -1;
        count = snprintf(command, 128, "AT+CIPCLOSE=%s\r\n", id);
        uart_write_blocking(uart1, command, count);

        if (getBlocks(buf, len, 10, "OK") < 0)
            return -1;
    }
    return 0;
}

int main()
{
    stdio_init_all();
    uint8_t buf[512];
    initWiFi();
    modeWiFi(buf, 512, 1);
    connectWiFi(buf, 512, "ssid", "password");
    getIPWiFi(buf, 512);
    startServerWiFi(buf, 512);
    sleep_ms(1000);
}

Program Listings

Master the Raspberry Pi Pico in C:

WiFi with lwIP & mbedtls

picomaster360

 

We have decided not to make the programs available as a download because this is not the point of the book - the programs are not finished production code but something you should type in and study.

The best solution is to provide the source code of the programs in a form that can be copied and pasted into a NetBeans or VS Code project. 

The only downside is that you have to create a project to paste the code into.

To do this follow the instructions in the book.

All of the programs below were copy and pasted from working programs in the IDE. They have been formatted using the built in formatter and hence are not identical in layout to the programs in the book. This is to make copy and pasting them easier. The programs in the book are formatted to be easy to read on the page.

Also notice that you will find complete listings of programs that are only slighly modified in the book and therefore not includes as a complete listing.The CMakeLists and other configuration files are also included here for completeness.

If anything you consider important is missing or if you have any requests or comments  contact:

This email address is being protected from spambots. You need JavaScript enabled to view it.


CHAPTER 1

Page 20 WiFi Simple Connect  Main program 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

int setup(uint32_t country, const char *ssid, const char *pass,  uint32_t auth)
{
   if (cyw43_arch_init_with_country(country))
  {
    return 1;
  }
  cyw43_arch_enable_sta_mode();
  if (cyw43_arch_wifi_connect_blocking(ssid, pass, auth))
  {
    return 2;
  }
}

char ssid[] = "myhost";
char pass[] = "mypassword";
uint32_t country = CYW43_COUNTRY_mycountry;
uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;

int main()
{
    stdio_init_all();
    setup(country, ssid, pass, auth);
    while (true)
    {
        sleep_ms(1);
    }
}

Page 21 WiFi Connect  CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()


add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})
target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background )
pico_add_extra_outputs(main)

Page 21 WiFi Connect lwiopts.h  - basic configuration file not listed in book

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H 

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#endif /* __LWIPOPTS_H__ */

 

 

Page 25 WiFi Connect setupWifi.h - used in most examples to connect to the AP.

int setup(uint32_t country, const char *ssid, const char *pass,
          uint32_t auth, const char *hostname, ip_addr_t *ip,
          ip_addr_t *mask, ip_addr_t *gw)
{

    if (cyw43_arch_init_with_country(country))
    {
        return 1;
    }

    cyw43_arch_enable_sta_mode();
    if (hostname != NULL)
    {
        netif_set_hostname(netif_default, hostname);
    }
    if (cyw43_arch_wifi_connect_async(ssid, pass, auth))
    {
        return 2;
    }
    int flashrate = 1000;
    int status = CYW43_LINK_UP + 1;
    while (status >= 0 && status != CYW43_LINK_UP)
    {
        int new_status = cyw43_tcpip_link_status(&cyw43_state,
                                                 CYW43_ITF_STA);
        if (new_status != status)
        {
            status = new_status;
            flashrate = flashrate / (status + 1);
            printf("connect status: %d %d\n", status, flashrate);
        }
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        sleep_ms(flashrate);
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
        sleep_ms(flashrate);
    }
    if (status < 0)
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
    }
    else
    {
        cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
        if (ip != NULL)
        {
            netif_set_ipaddr(netif_default, ip);
        }
        if (mask != NULL)
        {
            netif_set_netmask(netif_default, mask);
        }
        if (gw != NULL)
        {
            netif_set_gw(netif_default, gw);
        }

        printf("IP: %s\n",
               ip4addr_ntoa(netif_ip_addr4(netif_default)));
        printf("Mask: %s\n",
               ip4addr_ntoa(netif_ip_netmask4(netif_default)));
        printf("Gateway: %s\n",
               ip4addr_ntoa(netif_ip_gw4(netif_default)));
        printf("Host Name: %s\n",
               netif_get_hostname(netif_default));
    }
    return status;
}

int connect()
{
    char ssid[] = "ssid";
    char pass[] = "password";
    uint32_t country = CYW43_COUNTRY_code;
    uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
    return  setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);
}

Page 28 Scan main program  

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

static int scan_result(void *env, const cyw43_ev_scan_result_t *result)
{
    if (result)
    {
        printf("ssid: %-32s rssi: %4d chan: %3d mac: %02x:%02x:%02x:%02x:%02x:%02x sec: %u\n",
               result->ssid, result->rssi, result->channel,
               result->bssid[0], result->bssid[1], result->bssid[2], result->bssid[3], result->bssid[4], result->bssid[5],
               result->auth_mode);
    }
    return 0;
}

int main()
{
    stdio_init_all();

    if (cyw43_arch_init())
    {
        printf("failed to initialise\n");
        return 1;
    }

    cyw43_arch_enable_sta_mode();
    cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_STA, true, CYW43_COUNTRY_UK);
    cyw43_wifi_scan_options_t scan_options = {0};
    int err = cyw43_wifi_scan(&cyw43_state, &scan_options, NULL, scan_result);

    while (true)
    {
        if (!cyw43_wifi_scan_active(&cyw43_state))
            break;
        sleep_ms(1000);
        printf("Scan in progress \n");
    }
    printf("Scan Complete\n");
    cyw43_arch_deinit();
    return 0;
}

Page 29 Get RSSI main program

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "setupWifi.h"

int main()
{
    stdio_init_all();
    connect();
    int32_t rssi;
    while (true)
    {
        sleep_ms(1000);
        cyw43_wifi_get_rssi(&cyw43_state, &rssi);
        printf("rssi: %d \n", rssi);
    }
}
 

Chapter 2

Page 38 Python HTTP Server

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):

    def sendResponse(self, cmd):
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        self.send_response(200)
        self.end_headers()
        response = BytesIO()
        response.write(b'This is a '+bytes(cmd, 'utf-8')+
                                               b' request. ')
        response.write(b'Received: ')
        response.write(body)
        self.wfile.write(response.getvalue())

    def do_GET(self):
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b'Hello, world!')


    def do_HEAD(self):
        self.send_response(200)
        self.end_headers()

    def do_POST(self):
        self.sendResponse("POST")

    def do_PUT(self):
        self.sendResponse("PUT")

    def do_DELETE(self):
        self.sendResponse("DELETE")

    def do_PATCH(self):
        self.sendResponse("PATCH")


httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

Page 42  Simple HTTP Client using standard  lwipopts.h and cmakelists.txt 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/tcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\nConnection: close\r\n\r\n";

err_t recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
 if (p != NULL)
 {
 printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
 pbuf_copy_partial(p, myBuff, p->tot_len, 0);
 myBuff[p->tot_len] = 0;
 printf("Buffer= %s\n", myBuff);
 tcp_recved(pcb, p->tot_len);
 pbuf_free(p);
 }
 return ERR_OK;
}

static err_t connected(void *arg, struct tcp_pcb *pcb, err_t err)
{
 err = tcp_write(pcb, header, strlen(header), 0);
 err = tcp_output(pcb);
 return ERR_OK;
}

int main()
{

 stdio_init_all();
 connect();

    struct tcp_pcb *pcb = tcp_new();
    tcp_recv(pcb, recv);
    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = tcp_connect(pcb, &ip, 80, connected);
    cyw43_arch_lwip_end();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 44 Simple HTTP Client Using ALTCP

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        pbuf_copy_partial(p, myBuff, p->tot_len, 0);
        myBuff[p->tot_len] = 0;
        printf("Buffer= %s\n", myBuff);
        altcp_recved(pcb, p->tot_len);
        pbuf_free(p);
    }
    return ERR_OK;
}

static err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    err = altcp_write(pcb, header, strlen(header), 0);
    err = altcp_output(pcb);
    return ERR_OK;
}

int main()
{

    stdio_init_all();
    connect();

    struct altcp_pcb *pcb = altcp_new(NULL);
    altcp_recv(pcb, recv);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 80, altcp_client_connected);
    cyw43_arch_lwip_end();

    while (true)
    {
        sleep_ms(500);
    }
}
 

Add to the end of lwipopts.h

#define LWIP_ALTCP 1
 

 

Page 45 Not listed in full in book
Final Practical HTTP Client main.c - standard cmakelists.txt and lwipopts.h with  #define LWIP_ALTCP 1

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
                if ((p->tot_len) > 2)
        {
        pbuf_copy_partial(p, myBuff, p->tot_len, 0);
        myBuff[p->tot_len] = 0;        
        printf("Buffer= %s\n", myBuff);
        altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }    else
    {
        printf("Connection Closed");
        altcp_close(pcb);
    }
    return ERR_OK;
}

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    err = altcp_write(pcb, header, strlen(header), 0);
    err = altcp_output(pcb);

    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb){
        printf("Connection Closed");
        altcp_close(pcb);
}


int main()
{

    stdio_init_all();
    connect();

    struct altcp_pcb *pcb = altcp_new(NULL);
    altcp_recv(pcb, recv);
    altcp_sent(pcb, sent);
    altcp_err(pcb, err);
    altcp_poll(pcb, poll,10);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 80, altcp_client_connected);
    cyw43_arch_lwip_end();

    while (true)
    {
        sleep_ms(500);
    }
}

 


 

Chapter 3

Page 54 Not listed in full in book

Simple integer state request

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, myBuff, p->tot_len, 0);
            myBuff[p->tot_len] = 0;
            *(int *)arg = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        printf("Connection Closed \n");
        altcp_close(pcb);
        *(int *)arg = 6;
    }
    return ERR_OK;
}

static err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    *(int *)arg = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    *(int *)arg = 6;
    altcp_close(pcb);
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

int main()
{
    stdio_init_all();
    connect();

    int state = 0;
    struct altcp_pcb *pcb = altcp_new(NULL);

    altcp_recv(pcb, recv);
    altcp_sent(pcb, sent);
    altcp_err(pcb, err);
    altcp_poll(pcb, poll, 10);
    altcp_arg(pcb, &state);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 80, altcp_client_connected);
    cyw43_arch_lwip_end();
    state = 1;

    while (state != 0)
    {
        switch (state)
        {
        case 0:
        case 1:
        case 3:
            break;

        case 2:
            state = 3;
            cyw43_arch_lwip_begin();
            err = altcp_write(pcb, header, strlen(header), 0);
            err = altcp_output(pcb);
            cyw43_arch_lwip_end();
            break;
        case 4:
            state = 5;
            break;
        case 6:
            printf("Buffer= %s\n", myBuff);
            state = 0;
            break;
        default:
            sleep_ms(1000);
            printf("LED Flash\n");
        }
    }
    printf("Data Transfered\n");
}

Page 59 State use a struct

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *myBuff;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->myBuff) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->myBuff[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        printf("Connection Closed\n");
        altcp_close(pcb);
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
    altcp_close(pcb);
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

err_t newConnection(struct connectionState *cs, char *buf)
{
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->myBuff = buf;
    cs->start = 0;
    return ERR_OK;
}

int pollConnection(struct connectionState *cs)
{

    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
    case 6:
        break;
    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, header, strlen(header), 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    }
    return cs->state;
}

int main()
{
    stdio_init_all();
    connect();

    struct connectionState cs;
    newConnection(&cs, myBuff);

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs.pcb, &ip, 80, connected);
    cyw43_arch_lwip_end();
    cs.state = 1;
    while (true)
    {
        if (pollConnection(&cs) == 6)
        {
            printf("Buffer= %s\n", cs.myBuff);
            cs.state = 0;
            break;
        }
        sleep_ms(1000);
        printf("LED Flash\n");
    }
    printf("Data Transfered\n");
}

 

Page 65 Non blocking general Request.h

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *sendData;
    char *recvData;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->recvData) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->recvData[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {            
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

struct connectionState *newConnection(char *sendData, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *doRequest(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, char *recvData)
{
    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n%s";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    char *requestData = malloc(len + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    struct connectionState *cs = newConnection(requestData, recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

int pollRequest(struct connectionState **pcs)
{
    if(*pcs==NULL) return 0;
    struct connectionState *cs=*pcs;
    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
        break;

    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, cs->sendData, strlen(cs->sendData), 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    case 6:
        cyw43_arch_lwip_begin();
        altcp_close(cs->pcb);
        cyw43_arch_lwip_end();
        free(cs);
        *pcs = NULL;
        return 0;
    }
    return cs->state;
}
 

Page 27 Non blocking Request main program downloading two requests.

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "lwip/altcp.h"
#include "setupWifi.h"
#include "request.h"
#define BUF_SIZE 2048
char myBuff1[BUF_SIZE];
char myBuff2[BUF_SIZE];

int main()
{
    stdio_init_all();
    connect();

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    struct connectionState *cs1 = doRequest(&ip, "example.com", 80, "GET", "/", NULL, myBuff1);
    IP4_ADDR(&ip, 192, 168, 11, 101);
    struct connectionState *cs2 = doRequest(&ip, "192.168.11.101", 8080, "PUT", "/", "Hello PUT world", myBuff2);

    while (pollRequest(&cs1) + pollRequest(&cs2))
    {
        sleep_ms(100);
    }
    printf("Both complete\n");
    printf("Buffer 1 = \n%s\n\n", myBuff1);
    printf("Buffer 2 = \n%s\n\n", myBuff2);

    printf("Data Transferred\n");
    cyw43_arch_deinit();
    return 0;
}
 
 

Page 70 Temperature PUT client main program

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#include "request.h"

#define BUF_SIZE 4096
char myBuff1[BUF_SIZE];

int readTemp()
{
    return 33;
}

int main()
{
    char ssid[] = "laribina";
    char pass[] = "hawkhawk";
    uint32_t country = CYW43_COUNTRY_UK;
    uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);

    ip_addr_t ip;
    IP4_ADDR(&ip, 192, 168, 11, 101);

    while (true)
    {
        int t = readTemp();
        int len = snprintf(NULL, 0, "%d", t);
        char *requestData = malloc(len + 1);
        snprintf(requestData, len + 1, "%d", t);
        printf("%s\n",requestData);
        struct connectionState *cs1 = doRequest(&ip, "192.168.11.101", 8080, "PUT", "/", requestData, myBuff1);
        while (pollRequest(&cs1) )
        {
            sleep_ms(200);
        }
        printf("%s\n",myBuff1);
        sleep_ms(5000);
    }
    return 0;
}
 
 
 

Page 71 Custom Sever For the PUT Temperature Client

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def log_message(self,*args, **kwargs):
        pass

    def do_PUT(self):
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        bodyString= body.decode(encoding="utf-8")
        temp=float(bodyString)
        print(temp,"C")
        self.send_response(200)
        self.end_headers()

httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

Page 72 full listing not in book

Binary request version of request.h

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *sendData;
    int bytes;
    char *recvData;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->recvData) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->recvData[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

struct connectionState *newConnection(char *sendData, int bytes, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->bytes=bytes;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *doRequest(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, char *recvData)
{
    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n%s";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    char *requestData = malloc(len + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    struct connectionState *cs = newConnection(requestData, strlen(requestData),recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

struct connectionState *doRequestBinary(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, int bytes, char *recvData)
{

    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, bytes);
    char *requestData = malloc(len + bytes + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, bytes);
    memcpy(requestData + len, sendData, bytes);
    struct connectionState *cs = newConnection(requestData, len + bytes, recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

int pollRequest(struct connectionState **pcs)
{
    if (*pcs == NULL)
        return 0;
    struct connectionState *cs = *pcs;
    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
        break;

    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, cs->sendData, cs->bytes, 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    case 6:
        cyw43_arch_lwip_begin();
        altcp_close(cs->pcb);
        cyw43_arch_lwip_end();
        free(cs);
        *pcs = NULL;
        return 0;
    }
    return cs->state;
}

Page 74 Binary request main program

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "lwip/altcp.h"

#include "request.h"

#define BUF_SIZE 4096
char myBuff1[BUF_SIZE];

int main()
{
    char ssid[] = "laribina";
    char pass[] = "hawkhawk";
    uint32_t country = CYW43_COUNTRY_UK;
    uint32_t auth = CYW43_AUTH_WPA2_MIXED_PSK;
    stdio_init_all();
    setup(country, ssid, pass, auth, "MyPicoW", NULL, NULL, NULL);

    char randdata[500];
    ip_addr_t ip;
    IP4_ADDR(&ip, 192, 168, 11, 101);
    for (int p = 0; p < 500; p++)
    {
        randdata[p] = (uint8_t)rand();
    }
    struct connectionState *cs1 = doRequestBinary(&ip, "192.168.11.101", 8080, "PUT", "/", randdata, 500, myBuff1);
    while (pollRequest(&cs1))
    {
        sleep_ms(200);
    }
    printf("%s\n", myBuff1);

    return 0;
}

Page 75 Python Custom server for Binary request

from http.server import HTTPServer, BaseHTTPRequestHandler
from io import BytesIO

class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def log_message(self,*args, **kwargs):
        pass

    def do_PUT(self):  
        content_length = int(self.headers['Content-Length'])
        body = self.rfile.read(content_length)
        print(content_length)      
        with open("data.bin",mode="wb") as f:
            f.write(body)  
        self.send_response(200)
        self.end_headers()
        response = BytesIO()
        response.write(b'Received:' )      
        self.wfile.write(response.getvalue())

httpd = HTTPServer(('', 8080), SimpleHTTPRequestHandler)
httpd.serve_forever()

Page 77 full listing not in book

DNS Main Program needs requests.h 

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "lwip/altcp.h"
#include "lwip/dns.h"
#include "setupWifi.h"
#include "request.h"
#define BUF_SIZE 2048
char myBuff1[BUF_SIZE];

void dns_found(const char *name, const ip_addr_t *ip, void *arg)
{
    ip_addr_t *ipResult = (ip_addr_t *)arg;
    if (ip)
    {
        ip4_addr_copy(*ipResult, *ip);
    }
    else
    {
        ip4_addr_set_loopback(ipResult);
    }
    return;
}

err_t getIP(char *URL, ip_addr_t *ipResult)
{
    cyw43_arch_lwip_begin();
    err_t err = dns_gethostbyname(URL, ipResult, dns_found, ipResult);
    cyw43_arch_lwip_end();
    return err;
}

int main()
{
    stdio_init_all();
    connect();

    ip_addr_t ip;
    ip4_addr_set_zero(&ip);
    getIP("example.com", &ip);
    while (!ip_addr_get_ip4_u32(&ip))
    {
        sleep_ms(100);
    };
    if (ip4_addr_isloopback(&ip))
    {
        printf("address not found");
    }
    struct connectionState *cs1 = doRequest(&ip, "example.com", 80, "GET", "/", NULL, myBuff1);

    while (pollRequest(&cs1))
    {
        sleep_ms(100);
    }
    printf("Buffer 1 = \n%s\n\n", myBuff1);

    printf("Data Transferred\n");
    cyw43_arch_deinit();
    return 0;
}


Chapter 4

Page 90  Simple TLS Client  main.c

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"

#include "setupWifi.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];
char header[] = "GET /index.html HTTP/1.1\r\nHOST:example.com\r\n\r\n";

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{

    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        pbuf_copy_partial(p, myBuff, p->tot_len, 0);
        myBuff[p->tot_len] = 0;
        printf("Buffer= %s\n", myBuff);
        altcp_recved(pcb, p->tot_len);
        pbuf_free(p);
    }
    return ERR_OK;
}

static err_t altcp_client_connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    err = altcp_write(pcb, header, strlen(header), 0);
    err = altcp_output(pcb);

    return ERR_OK;
}

int main()
{

    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    struct altcp_pcb *pcb = altcp_tls_new(tls_config, IPADDR_TYPE_ANY);
    mbedtls_ssl_set_hostname(altcp_tls_context(pcb), "example.com");
    altcp_recv(pcb, recv);



    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(pcb, &ip, 443, altcp_client_connected);
    cyw43_arch_lwip_end();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 90 Simple TLS Client cmakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()


add_executable(main
 main.c
)


target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mbedtls
pico_mbedtls)
pico_add_extra_outputs(main)

Page 88 Simple TLS Client mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
 #define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C
//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 90 full listing not in book

Simple TLS Client lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1
#define LWIP_ALTCP_TLS           1
#define LWIP_ALTCP_TLS_MBEDTLS   1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG  LWIP_DBG_ON

#endif /* __LWIPOPTS_H__ */

Page 92 Full listing not in book

TLS Request.h

struct connectionState
{
    int state;
    struct altcp_pcb *pcb;
    char *sendData;
    int bytes;
    char *recvData;
    int start;
};

err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    printf("data sent %d\n", len);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        if ((p->tot_len) > 2)
        {
            pbuf_copy_partial(p, (cs->recvData) + (cs->start), p->tot_len, 0);
            cs->start += p->tot_len;
            cs->recvData[cs->start] = 0;
            cs->state = 4;
            altcp_recved(pcb, p->tot_len);
        }
        pbuf_free(p);
    }
    else
    {
        cs->state = 6;
    }
    return ERR_OK;
}

static err_t connected(void *arg, struct altcp_pcb *pcb, err_t err)
{
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 2;
    return ERR_OK;
}

err_t poll(void *arg, struct altcp_pcb *pcb)
{
    printf("Connection Closed \n");
    struct connectionState *cs = (struct connectionState *)arg;
    cs->state = 6;
}

void err(void *arg, err_t err)
{
    if (err != ERR_ABRT)
    {
        printf("client_err %d\n", err);
    }
}

struct connectionState *newConnection(char *sendData, int bytes, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;
    cs->pcb = altcp_new(NULL);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->bytes=bytes;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *newTLSConnection(char* host, char *sendData, int bytes, char *recvData)
{
    struct connectionState *cs = (struct connectionState *)malloc(sizeof(struct connectionState));
    cs->state = 0;

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    cs->pcb = altcp_tls_new(tls_config, IPADDR_TYPE_ANY);    
    mbedtls_ssl_set_hostname(altcp_tls_context(cs->pcb), host);
    altcp_recv(cs->pcb, recv);
    altcp_sent(cs->pcb, sent);
    altcp_err(cs->pcb, err);
    altcp_poll(cs->pcb, poll, 10);
    altcp_arg(cs->pcb, cs);
    cs->sendData = sendData;
    cs->bytes=bytes;
    cs->recvData = recvData;
    cs->start = 0;
    return cs;
}

struct connectionState *doRequest(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, char *recvData)
{
    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n%s";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    char *requestData = malloc(len + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, strlen(sendData), sendData);
    struct connectionState *cs = newConnection(requestData, strlen(requestData),recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}

struct connectionState *doRequestBinary(ip_addr_t *ip, char *host, u16_t port, char *request, char *file, char *sendData, int bytes, char *recvData)
{

    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, bytes);
    char *requestData = malloc(len + bytes + 1);
    snprintf(requestData, len + 1, headerTemplate, request, file, host, port, bytes);
    memcpy(requestData + len, sendData, bytes);
    struct connectionState *cs = newConnection(requestData, len + bytes, recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}


struct connectionState *doTLSRequestBinary(ip_addr_t *ip, char *host, u16_t port, char *request, char *file,  char *sendData,int bytes, char *recvData)
{

    char headerTemplate[] = "%s %s HTTP/1.1\r\nHOST:%s:%d\r\nConnection: close\r\nContent-length: %d\r\n\r\n";
    int len = snprintf(NULL, 0, headerTemplate, request, file, host, port, bytes);
    char *requestData = malloc(len + bytes+1);
    snprintf(requestData, len+1, headerTemplate, request, file, host, port, bytes);
    memcpy(requestData+len,sendData,bytes);  
    struct connectionState *cs = newTLSConnection(host,requestData,len+bytes ,recvData);
    cyw43_arch_lwip_begin();
    err_t err = altcp_connect(cs->pcb, ip, port, connected);
    cyw43_arch_lwip_end();
    cs->state = 1;
    return cs;
}


int pollRequest(struct connectionState **pcs)
{
    if (*pcs == NULL)
        return 0;
    struct connectionState *cs = *pcs;
    switch (cs->state)
    {
    case 0:
    case 1:
    case 3:
        break;

    case 2:
        cs->state = 3;
        cyw43_arch_lwip_begin();
        err_t err = altcp_write(cs->pcb, cs->sendData, cs->bytes, 0);
        err = altcp_output(cs->pcb);
        cyw43_arch_lwip_end();
        break;
    case 4:
        cs->state = 5;
        break;
    case 6:
        cyw43_arch_lwip_begin();
        altcp_close(cs->pcb);
        cyw43_arch_lwip_end();
        free(cs);
        *pcs = NULL;
        return 0;
    }
    return cs->state;
}

Page 94 RequestTLS Client Main.c

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/altcp_tcp.h"
#include "lwip/altcp_tls.h"
#include "setupWifi.h"

#include "request.h"

#define BUF_SIZE 2048
char myBuff[BUF_SIZE];

int main()
{

    stdio_init_all();
    connect();

    ip_addr_t ip;
    IP4_ADDR(&ip, 93, 184, 216, 34);

    struct connectionState *cs1 = doTLSRequestBinary(&ip, "example.com", 443, "GET", "/", NULL, 0, myBuff);
    while (pollRequest(&cs1))
    {
        sleep_ms(200);
    }
    printf("%s\n", myBuff);

    return 0;
}

Chapter 5

Page 105 RandomByte function

uint8_t randomByte()
{
    uint32_t random = 0;
    uint32_t bit = 0;
    for (int k = 0; k < 8; k++)
    {
        while (true)
        {
            bit = rosc_hw->randombit;
            sleep_us(10);
            if (bit != rosc_hw->randombit)
                break;
        }

        random = (random << 1) | bit;
    }

    return (uint8_t)random;
}

Page 111 Full listing not in book

Adding EC and GCM to mbedtls_config.h in Client and server mode

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C



//EC KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C

/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

#define MBEDTLS_SSL_SRV_C

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 115 AES ECB Mode Main Program

#include <stdio.h>
#include "pico/stdlib.h"
#include "mbedtls/cipher.h"

#include "pico/rand.h"

int main()
{
    stdio_init_all();
    int ret;


    mbedtls_cipher_context_t cipher_ctx;
    mbedtls_cipher_init(&cipher_ctx);

    const mbedtls_cipher_info_t *cipher_info;
    cipher_info = mbedtls_cipher_info_from_string("AES-128-ECB");
    ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info);

    unsigned char key[16];
    get_rand_128((rng_128_t*)key );


    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_ENCRYPT);
    ret = mbedtls_cipher_reset(&cipher_ctx);

    char buffer[16] = "Hello World";
    char output[16];
    int olen;
    ret = mbedtls_cipher_update(&cipher_ctx, buffer, 16, output, &olen);
    printf("cipher text ");
    for (int i = 0; i < olen; i++)
    {
        printf("%02X", output[i]);
    }
    printf("\n");

    char plaintext[16];  
    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_DECRYPT);
    ret = mbedtls_cipher_reset(&cipher_ctx);
    mbedtls_cipher_update(&cipher_ctx, output, 16, plaintext, &olen);
    printf("plain text %.16s\n", plaintext);
    return 0;
}

Page 116 AES ECB mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES

#define MBEDTLS_CIPHER_C

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 116 AES ECB Mode CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

 add_executable(main

   main.c
)
target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_mbedtls)
pico_add_extra_outputs(main)

Page 118 Full listing not in book

AES CBC Mode Main Program including list of available encryptions.

#include <stdio.h>
#include "pico/stdlib.h"
#include "mbedtls/cipher.h"

#include "pico/rand.h"

int main()
{
    stdio_init_all();
    int ret;

    const mbedtls_cipher_info_t *cipher_info1;
    const int *list;
    printf("Available ciphers:\n");
    list = mbedtls_cipher_list();
    while (*list)
    {
        cipher_info1 = mbedtls_cipher_info_from_type(*list);
        printf("  %s\n", cipher_info1->name);
        list++;
    }

    mbedtls_cipher_context_t cipher_ctx;
    mbedtls_cipher_init(&cipher_ctx);

    const mbedtls_cipher_info_t *cipher_info;
    cipher_info = mbedtls_cipher_info_from_string("AES-128-CBC");
    ret = mbedtls_cipher_setup(&cipher_ctx, cipher_info);

    unsigned char key[16];
    get_rand_128((rng_128_t *)key);
    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_ENCRYPT);

    unsigned char IV[16];
    get_rand_128((rng_128_t *)IV);
    ret = mbedtls_cipher_set_iv(&cipher_ctx, IV, 16);

    ret = mbedtls_cipher_reset(&cipher_ctx);

    char buffer[16] = "Hello World";
    char output[16];
    int olen;
    ret = mbedtls_cipher_update(&cipher_ctx, buffer, 16, output, &olen);

    printf("cipher text ");
    for (int i = 0; i < olen; i++)
    {
        printf("%02X", output[i]);
    }
    printf("\n");

    char plaintext[16];
    ret = mbedtls_cipher_setkey(&cipher_ctx, key, cipher_info->key_bitlen, MBEDTLS_DECRYPT);   
    ret = mbedtls_cipher_set_iv(&cipher_ctx, IV, 16);
    ret = mbedtls_cipher_reset(&cipher_ctx);
    ret = mbedtls_cipher_update(&cipher_ctx, output, 16, plaintext, &olen);
    printf("plain text %.16s\n", plaintext);
    return 0;
}

Chapter 6

Page 130 Simple HTTP Server Main Program 

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/altcp_tcp.h"

#include "hardware/rtc.h"
#include "time.h"

#include "setupWifi.h"

#define BUF_SIZE 2048

void getDateNow(struct tm *t)
{
    datetime_t rtc;
    rtc_get_datetime(&rtc);

    t->tm_sec = rtc.sec;
    t->tm_min = rtc.min;
    t->tm_hour = rtc.hour;
    t->tm_mday = rtc.day;
    t->tm_mon = rtc.month - 1;
    t->tm_year = rtc.year - 1900;
    t->tm_wday = rtc.dotw;
    t->tm_yday = 0;
    t->tm_isdst = -1;
}

void sendData(struct altcp_pcb *pcb)
{
    err_t err;
    char html[] = "<html><head><title>Temperature</title></head><body><p>{\"humidity\":81%, \"airtemperature\":23.5C}</p></body></html>\r\n";
    char headers[1024] = {0};
    char Status[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=UTF-8\r\nServer:Picow\r\n";

    struct tm t;
    getDateNow(&t);
    char Date[100];
    strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", &t);

    char ContLen[100] = {0};
    snprintf(ContLen, sizeof ContLen, "Content-Length:%d \r\n", strlen(html));
    snprintf(headers, sizeof headers, "%s%s%s\r\n", Status, Date, ContLen);

    char data[2048] = {0};
    snprintf(data, sizeof data, "%s%s", headers, html);

    err = altcp_write(pcb, data, strlen(data), 0);
    err = altcp_output(pcb);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    char myBuff[BUF_SIZE];
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        pbuf_copy_partial(p, myBuff, p->tot_len, 0);
        myBuff[p->tot_len] = 0;
        printf("Buffer= %s\n", myBuff);
        altcp_recved(pcb, p->tot_len);
        pbuf_free(p);
        sendData(pcb);
    }
    return ERR_OK;
}

static err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    altcp_close(pcb);
}

static err_t accept(void *arg, struct altcp_pcb *pcb, err_t err)
{
    altcp_recv(pcb, recv);
    altcp_sent(pcb, sent);
    printf("connect!\n");

    return ERR_OK;
}

void setRTC()
{
    datetime_t t = {
        .year = 2023,
        .month = 02,
        .day = 03,
        .dotw = 5,
        .hour = 11,
        .min = 10,
        .sec = 00};
    rtc_init();
    rtc_set_datetime(&t);
}

int main()
{
    stdio_init_all();
    setRTC();
    connect();
    struct altcp_pcb *pcb = altcp_new(NULL);
    altcp_accept(pcb, accept);

    altcp_bind(pcb, IP_ADDR_ANY, 80);
    cyw43_arch_lwip_begin();
    pcb = altcp_listen_with_backlog(pcb, 3);
    cyw43_arch_lwip_end();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 133 Full listing not in book

Simple HTTP Server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1

#define LWIP_DEBUG 1
#define TCP_LISTEN_BACKLOG       1
#endif /* __LWIPOPTS_H__ */

Page 113 Full listing not in book

Simple HTTP Server CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background hardware_rtc)
pico_add_extra_outputs(main)

Page 136 Python program to convert certificate to C code

import binascii

with open("iopress.key", 'rb') as f:
    lines = f.readlines()
lines = b"".join(lines[1:-1])
key = binascii.a2b_base64(lines)

res = ""

for b in key:
    res += "0x%02x," % b

res="u8_t key[]={"+res[:-1]+"};"
print(res)

with open("iopress.crt", 'rb') as f:
    lines = f.readlines()
lines = b"".join(lines[1:-1])
cert = binascii.a2b_base64(lines)
res = ""
for b in cert:
    res += "0x%02x," % b

res="u8_t cert[]={"+res[:-1]+"};"
print()
print(res)

Page 137 Full listing not in book

Simple HTTPS Server Main Program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/altcp_tcp.h"

#include "lwip/altcp_tls.h"
#include "hardware/structs/rosc.h"

#include "hardware/rtc.h"
#include "time.h"

#include "setupWifi.h"

#define BUF_SIZE 2048

void getDateNow(struct tm *t)
{
    datetime_t rtc;
    rtc_get_datetime(&rtc);

    t->tm_sec = rtc.sec;
    t->tm_min = rtc.min;
    t->tm_hour = rtc.hour;
    t->tm_mday = rtc.day;
    t->tm_mon = rtc.month - 1;
    t->tm_year = rtc.year - 1900;
    t->tm_wday = rtc.dotw;
    t->tm_yday = 0;
    t->tm_isdst = -1;
}

void sendData(struct altcp_pcb *pcb)
{
    err_t err;
    char html[] = "<html><head><title>Temperature</title></head><body><p>{\"humidity\":81%, \"airtemperature\":23.5C}</p></body></html>\r\n";
    char headers[1024] = {0};
    char Status[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=UTF-8\r\nServer:Picow\r\n";

    struct tm t;
    getDateNow(&t);
    char Date[100];
    strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", &t);

    char ContLen[100] = {0};
    snprintf(ContLen, sizeof ContLen, "Content-Length:%d \r\n", strlen(html));
    snprintf(headers, sizeof headers, "%s%s%s\r\n", Status, Date, ContLen);

    char data[2048] = {0};
    snprintf(data, sizeof data, "%s%s", headers, html);

    err = altcp_write(pcb, data, strlen(data), 0);
    err = altcp_output(pcb);
}

err_t recv(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
{
    char myBuff[BUF_SIZE];
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d err %d\n", p->tot_len, p->len, p->next, err);
        pbuf_copy_partial(p, myBuff, p->tot_len, 0);
        myBuff[p->tot_len] = 0;
        printf("Buffer= %s\n", myBuff);
        altcp_recved(pcb, p->tot_len);
        pbuf_free(p);
        sendData(pcb);
    }
    return ERR_OK;
}

static err_t sent(void *arg, struct altcp_pcb *pcb, u16_t len)
{
    altcp_close(pcb);
}

static err_t accept(void *arg, struct altcp_pcb *pcb, err_t err)
{
    altcp_recv(pcb, recv);
    altcp_sent(pcb, sent);
    printf("connect!\n");

    return ERR_OK;
}

void setRTC()
{
    datetime_t t = {
        .year = 2023,
        .month = 02,
        .day = 03,
        .dotw = 5,
        .hour = 11,
        .min = 10,
        .sec = 00};
    rtc_init();
    rtc_set_datetime(&t);
}

int main()
{
    stdio_init_all();
    setRTC();

    connect();

    u8_t key[] = {0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x1e, 0x04, 0x4b, 0xc5, 0xa4, 0xa0, 0x8b, 0x1a, 0xfd, 0x3d, 0xbb, 0xce, 0x74, 0x6d, 0xdc, 0x8a, 0xc4, 0x8a, 0x7b, 0x49, 0xae, 0x98, 0xc8, 0xf2, 0xbc, 0xae, 0xd4, 0xd8, 0xa4, 0x61, 0x14, 0x03, 0x2c, 0xd9, 0xea, 0xb6, 0xae, 0xe5, 0xbc, 0xc8, 0x35, 0x11, 0x04, 0x9c, 0x41, 0xc2, 0x47, 0xd4, 0x2c, 0x9c, 0x0c, 0xdc, 0x1f, 0x8f, 0xc5, 0xa9, 0xd7, 0xb8, 0xd1, 0xb4, 0x12, 0xf2, 0x44, 0x71, 0x22, 0x69, 0x83, 0x47, 0x84, 0x04, 0x8c, 0x23, 0x37, 0x98, 0xf0, 0xbe, 0x7a, 0x67, 0x48, 0xd7, 0x32, 0xd2, 0xf5, 0x8d, 0xf1, 0xf1, 0x6e, 0xf4, 0x4b, 0xa5, 0x48, 0x1c, 0xcc, 0x7d, 0xe0, 0xa9, 0xee, 0x9d, 0xf3, 0x39, 0x77, 0x64, 0x91, 0x07, 0x70, 0x27, 0xf0, 0x34, 0xa2, 0x21, 0xd8, 0xec, 0xd0, 0xe7, 0xeb, 0x43, 0xc3, 0x6a, 0x20, 0x23, 0x10, 0xfe, 0x42, 0x02, 0x6b, 0xda, 0x89, 0xf4, 0x41, 0x96, 0x64, 0x32, 0x52, 0x20, 0x05, 0x0d, 0x5b, 0xf3, 0x67, 0x51, 0xb7, 0x7d, 0xd1, 0x24, 0x0b, 0x2c, 0x33, 0x84, 0x5b, 0xf9, 0xed, 0x66, 0xe6, 0x3c, 0x4d, 0xdf, 0x09, 0x3e, 0xd5, 0xe5, 0x1c, 0x27, 0x2c, 0x81, 0xee, 0x03, 0x91, 0x8d, 0xc0, 0x2b, 0x3e, 0xd9, 0x37, 0x8e, 0x3d, 0xd1, 0x30, 0xd6, 0x97, 0x7b, 0x98, 0xfb, 0x80, 0x13, 0x5a, 0x84, 0x08, 0x90, 0x0d, 0x5c, 0x99, 0x51, 0x4f, 0x8f, 0xab, 0x0c, 0x39, 0x69, 0x76, 0xf8, 0xf4, 0xfd, 0xa7, 0x04, 0x8d, 0x72, 0x27, 0xa6, 0x1e, 0xbd, 0xff, 0x10, 0x43, 0xe8, 0x53, 0xe7, 0x08, 0xb8, 0xbd, 0x55, 0xb4, 0x7a, 0xa2, 0x44, 0xe9, 0xe7, 0x78, 0xf7, 0x11, 0x49, 0x01, 0x70, 0x60, 0xdf, 0xe8, 0xd1, 0xb0, 0x8c, 0xa2, 0x3d, 0x98, 0x07, 0x9b, 0x66, 0xff, 0xe8, 0x68, 0x33, 0x82, 0xe3, 0x75, 0x3d, 0x37, 0x8d, 0xf2, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe8, 0xc0, 0x12, 0x7f, 0x02, 0x98, 0x75, 0x23, 0xa6, 0x32, 0x92, 0x4e, 0x11, 0x27, 0xad, 0xda, 0x5b, 0x9e, 0xec, 0x9c, 0xa4, 0xb4, 0x26, 0x2b, 0x2b, 0xd4, 0xdb, 0x1a, 0x9e, 0xd5, 0xd3, 0xa8, 0xb4, 0x29, 0x58, 0x79, 0x96, 0x9f, 0x1a, 0xff, 0xdc, 0xef, 0x4c, 0xb3, 0x1b, 0x79, 0x36, 0xd3, 0x03, 0x4d, 0x08, 0x15, 0x54, 0xa7, 0x84, 0x2d, 0xc3, 0xb2, 0x44, 0x75, 0x15, 0x9f, 0x57, 0xae, 0x25, 0x64, 0xcc, 0x5f, 0xdf, 0x7d, 0xd3, 0xe9, 0xb7, 0xbc, 0xeb, 0x01, 0x92, 0xda, 0x9f, 0x7e, 0xc3, 0xc6, 0xce, 0xd9, 0xc2, 0x16, 0x5a, 0x52, 0x0c, 0x1e, 0xe2, 0x92, 0x4a, 0xf2, 0x33, 0x13, 0x78, 0x5f, 0xa3, 0xa8, 0x0d, 0x99, 0x75, 0x8d, 0x33, 0xd5, 0x71, 0xc6, 0x3c, 0x86, 0xf9, 0x36, 0xbf, 0x86, 0x2e, 0xc3, 0xfe, 0x63, 0x7d, 0x50, 0x94, 0xb6, 0x71, 0x7f, 0x9f, 0xb6, 0x55, 0xa5, 0x02, 0x81, 0x81, 0x00, 0xd0, 0xa6, 0xcd, 0xaf, 0x92, 0x3b, 0x7a, 0x2f, 0x17, 0xfd, 0xd1, 0x05, 0x6b, 0x9c, 0x95, 0xb7, 0x7b, 0x39, 0x0c, 0xa5, 0xde, 0xb1, 0xa4, 0x86, 0x87, 0x39, 0x73, 0xb0, 0x22, 0xb3, 0x7c, 0x6a, 0x14, 0xdc, 0x19, 0x98, 0xa7, 0xe7, 0x02, 0xdb, 0x54, 0xa0, 0xc3, 0xbc, 0x80, 0x54, 0x60, 0xb6, 0xa6, 0xf4, 0xc5, 0x01, 0xe1, 0xc3, 0xf7, 0xc3, 0xd2, 0xdb, 0xe7, 0x1f, 0xc9, 0xcc, 0x51, 0x66, 0x66, 0xd0, 0xce, 0x31, 0x5a, 0x31, 0x76, 0xb7, 0x98, 0x52, 0xda, 0x82, 0xe8, 0x33, 0xc8, 0xf0, 0x1a, 0x8f, 0x95, 0x46, 0x7f, 0x48, 0x72, 0x47, 0x1e, 0x33, 0x3c, 0x0f, 0xd7, 0x55, 0x21, 0xc3, 0xea, 0x10, 0x8e, 0xae, 0xbc, 0x18, 0xa5, 0xcc, 0x85, 0xf1, 0x09, 0x3d, 0x15, 0x82, 0xa0, 0x49, 0x55, 0xd6, 0x7f, 0x64, 0xe0, 0xb0, 0xf0, 0x17, 0x75, 0xbd, 0x92, 0xc7, 0x83, 0xe3, 0x59, 0x09, 0x02, 0x81, 0x81, 0x00, 0x88, 0x6b, 0xd4, 0x2b, 0x87, 0xcc, 0xee, 0x93, 0xe7, 0x9d, 0x2a, 0xae, 0x01, 0x56, 0x1d, 0x8b, 0xa8, 0x3a, 0x1d, 0x7b, 0xae, 0xfa, 0x3c, 0x88, 0xff, 0x56, 0xf2, 0xd9, 0xc6, 0x91, 0x94, 0x4f, 0x04, 0xd2, 0x5b, 0x1e, 0x61, 0x4f, 0x7e, 0x96, 0xcb, 0xdb, 0xa3, 0x3c, 0x33, 0xf5, 0x37, 0x52, 0x35, 0x54, 0x18, 0x51, 0xd0, 0x5d, 0xa3, 0x96, 0xe3, 0x66, 0x80, 0xc3, 0x93, 0xd9, 0xe2, 0x9d, 0x9b, 0x23, 0x5a, 0xbb, 0x33, 0x16, 0xe0, 0x77, 0xd4, 0x0f, 0x32, 0x3b, 0xa8, 0xe4, 0xe5, 0xa9, 0x7a, 0x7c, 0xf3, 0xcf, 0x24, 0xf8, 0xcf, 0x15, 0xda, 0x2e, 0xdc, 0x24, 0x5d, 0x33, 0x5b, 0x06, 0xa5, 0x7e, 0x81, 0x41, 0x46, 0x3f, 0x55, 0x6c, 0x5f, 0x1e, 0x53, 0x62, 0x9b, 0x25, 0x8d, 0xbb, 0x2e, 0x45, 0x2a, 0xf2, 0x0c, 0x10, 0x2a, 0x6a, 0x69, 0xd0, 0x09, 0xf4, 0x81, 0x1b, 0x71, 0x55, 0x02, 0x81, 0x80, 0x66, 0x63, 0x74, 0x4b, 0xd3, 0xd6, 0x9b, 0xfe, 0xc0, 0x27, 0x2d, 0x8b, 0x1b, 0x63, 0x9b, 0x94, 0x8e, 0x43, 0x50, 0x91, 0x94, 0xd6, 0x57, 0x86, 0x2c, 0x95, 0x64, 0xcf, 0xea, 0x37, 0x69, 0xb6, 0x24, 0xc6, 0x5d, 0x49, 0x2c, 0x1b, 0x90, 0xab, 0x50, 0xbc, 0x13, 0x51, 0x4d, 0x28, 0x1a, 0xcd, 0x86, 0xe0, 0x56, 0x4c, 0xb6, 0x1d, 0x14, 0x58, 0x64, 0x00, 0xc5, 0x4a, 0x34, 0x1c, 0xaf, 0x55, 0x30, 0xdf, 0x06, 0x4f, 0xf1, 0x92, 0x94, 0x4f, 0x43, 0xd0, 0x64, 0xaa, 0x18, 0x88, 0x50, 0xf2, 0x82, 0x16, 0x33, 0x8a, 0x84, 0xab, 0x68, 0x68, 0xbd, 0xc9, 0x26, 0x90, 0x1f, 0x7b, 0x07, 0x36, 0xbc, 0x85, 0xa3, 0x7e, 0xdb, 0x8e, 0xbc, 0xcd, 0xc0, 0x6c, 0xa7, 0xbb, 0xf1, 0xf2, 0x47, 0xf5, 0xb4, 0xc9, 0xad, 0x7a, 0x33, 0x48, 0xa0, 0x88, 0xe2, 0x9e, 0x44, 0x88, 0xe3, 0x8f, 0x8d, 0x01, 0x02, 0x81, 0x80, 0x04, 0xa3, 0xe0, 0xb3, 0x7e, 0xdd, 0x12, 0x94, 0x27, 0xb0, 0xac, 0x4b, 0x26, 0xfd, 0xb2, 0x5f, 0x2b, 0x91, 0x29, 0x5a, 0x0b, 0x2b, 0x9a, 0xeb, 0x08, 0x21, 0xde, 0x15, 0x79, 0x8a, 0x55, 0x0c, 0xec, 0xac, 0x85, 0x72, 0x11, 0xb6, 0x1d, 0x51, 0xf1, 0xa6, 0x28, 0xa0, 0x86, 0xae, 0x23, 0x7c, 0x4c, 0x2c, 0xfe, 0xce, 0xd4, 0xd3, 0xf2, 0x67, 0x47, 0x6c, 0xa7, 0xfd, 0xe6, 0x80, 0x4f, 0x8d, 0x54, 0xa9, 0x8a, 0xb8, 0x80, 0xc5, 0xbc, 0x6b, 0x7e, 0xe1, 0xc2, 0xa1, 0x24, 0xcf, 0x2d, 0xe1, 0x0c, 0x9f, 0x7b, 0x71, 0xcf, 0x75, 0xb2, 0x04, 0xf8, 0x51, 0xac, 0x07, 0x10, 0x56, 0x93, 0x46, 0x92, 0xdd, 0x1d, 0x5b, 0x1f, 0x94, 0x87, 0xcf, 0xe2, 0x99, 0x36, 0x89, 0xe7, 0xc2, 0x8a, 0x0a, 0x9e, 0x0d, 0x30, 0x17, 0xd5, 0x6d, 0xde, 0x10, 0x94, 0x47, 0x35, 0x89, 0x10, 0xe6, 0x8c, 0x0e};

    u8_t cert[] = {0x30, 0x82, 0x03, 0x6b, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x72, 0x8e, 0xfd, 0x0e, 0x52, 0x0a, 0x87, 0xdd, 0x55, 0x25, 0xee, 0x05, 0x11, 0x1d, 0x0d, 0xf7, 0xc8, 0x64, 0x5b, 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5b, 0x91, 0x51, 0xe1, 0x89, 0x20, 0xf5, 0xdf, 0x02, 0x94, 0x59, 0x76, 0x9e, 0xdc, 0x53, 0xf3, 0x17, 0x8f, 0x96, 0x17, 0xd1, 0x2f, 0x65, 0x36, 0xd4, 0x56, 0x7e, 0xd8, 0x0d, 0x7e, 0x59, 0x79, 0xab, 0x47, 0x67, 0x01, 0xb6, 0x9e, 0xf6, 0x7a, 0x0d, 0x20, 0xd2, 0xb2, 0x2d, 0x87, 0x84, 0x07, 0x40, 0x2d, 0x83, 0x1e, 0x16, 0x4f, 0x2d, 0x20, 0xaf, 0xf2, 0xca, 0xde, 0x10, 0x73, 0x41, 0xb9, 0x48, 0x3c, 0x4f, 0x9d, 0x55, 0xbc, 0xee, 0x68, 0xae, 0x66, 0x4d, 0x5d, 0x41, 0xa9, 0xbc, 0x51, 0x6d, 0xe2, 0x37, 0x0c, 0x0f, 0xf4, 0x43, 0xa0, 0x84, 0xf9, 0x40, 0xbc, 0x89, 0xaa, 0xcd, 0x14, 0xb4, 0xd5, 0xda, 0xd1, 0xb3, 0x2c, 0x4a, 0x56, 0x7e, 0x86, 0x2c, 0x71, 0xaa, 0x75, 0x86, 0x48, 0x14, 0x2a, 0xbc, 0x05, 0xab, 0x14, 0x72, 0x72, 0x01, 0xc8, 0xff, 0x02, 0x3d, 0x2e, 0xe9, 0xef, 0x21, 0x4d, 0x71, 0xf3, 0x0c, 0xba, 0x40, 0xfd, 0x9f, 0xb1, 0x40, 0xea, 0x47, 0x65, 0x3d, 0xb7, 0x52, 0xd8, 0xbb, 0x13, 0x30, 0x38, 0xb4, 0x3c, 0xbf, 0x76, 0x06, 0xe2, 0xb3, 0x3f, 0xf7, 0x7b, 0xdd, 0xdf, 0x54, 0x7b, 0x8d, 0x0c, 0x4d, 0x4a, 0x96, 0xcd, 0x14, 0x5c, 0x7d, 0xed, 0xb3, 0x2f, 0xbd, 0x27, 0xc8, 0x52, 0x6e, 0x58, 0x8e, 0x9c, 0x07, 0xa1, 0x52, 0xe2, 0x49, 0x8c, 0x04, 0x3f, 0x84, 0x32, 0x7b, 0xff, 0x5f, 0xf4, 0xf2, 0xdf, 0x3c, 0x73, 0xff, 0x9f, 0x63, 0x0e, 0xe5, 0x7f, 0xdf, 0xa8, 0x7e, 0x4d, 0xf3, 0x29, 0xd8, 0x2b, 0x41, 0x25, 0xbc, 0x73, 0x41, 0x3b, 0x1f, 0x39, 0x64, 0x48, 0x85, 0xe5, 0x66, 0x90, 0x8c, 0xd3, 0x8a, 0xce, 0xdc, 0xb5, 0x0d, 0x93, 0xb0, 0xd0, 0x8a, 0xef, 0x74, 0x8f, 0x28, 0x2f, 0x2c, 0x96, 0x4a, 0x4f, 0xc3, 0xf1, 0xde, 0x25, 0xff, 0xd4};
    struct altcp_tls_config *tls_config = altcp_tls_create_config_server_privkey_cert(key, sizeof(key), NULL, 0, cert, sizeof(cert));
    struct altcp_pcb *pcb = altcp_tls_new(tls_config, IPADDR_TYPE_ANY);

    altcp_accept(pcb, accept);

    altcp_bind(pcb, IP_ADDR_ANY, 443);
    cyw43_arch_lwip_begin();
    pcb = altcp_listen_with_backlog(pcb, 3);
    cyw43_arch_lwip_end();
    while (true)
    {
        sleep_ms(500);
    }
}

Page 137 Full listing not in book

Simple HTTPS Server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1
#define LWIP_ALTCP_TLS           1
#define LWIP_ALTCP_TLS_MBEDTLS   1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG  LWIP_DBG_ON
#define TCP_LISTEN_BACKLOG       1
#endif /* __LWIPOPTS_H__ */

Page 137 Full listing not in book

Simple HTTPS Server mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

#define MBEDTLS_SSL_SRV_C

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 137 Full listing not in book

Simple HTTPS Server CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background hardware_rtc pico_lwip_mbedtls pico_mbedtls)
pico_add_extra_outputs(main)

Page 140 Simple HTTP Bultin Server Main Program  

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/apps/httpd.h"
#include "setupWifi.h"

int main()
{
    stdio_init_all();
    connect();

    httpd_init();

    while (true)
    {
        sleep_ms(500);
    }
}

Page 140 Full listing not in book

Simple HTTP Bultin Server Cmakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_http)
pico_add_extra_outputs(main)

Page 140 Full listing not in book

Simple HTTP Bultin Server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384

#define LWIP_ALTCP 1

#define LWIP_DEBUG 1
#define TCP_LISTEN_BACKLOG 1

#endif /* __LWIPOPTS_H__ */

Page 141 Linux Cmakelists.txt for htmlgen

cmake_minimum_required(VERSION 3.13)
project(makefsdata C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

add_executable(htmlgen
 makefsdata.c
)

target_include_directories(htmlgen
         PRIVATE ../../../../src/include/
         PRIVATE ../../../../contrib/ports/unix/port/include/
         PRIVATE ${CMAKE_CURRENT_LIST_DIR})

Page 141 Windows Cmakelists.txt for htmlgen

cmake_minimum_required(VERSION 3.13)

project(makefsdata C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

add_executable(htmlgen
 makefsdata.c
)

target_include_directories(htmlgen
         PRIVATE ../../../../src/include/

         PRIVATE ../../../../contrib/ports/win32/include/

         PRIVATE ${CMAKE_CURRENT_LIST_DIR})

Page 151

Simple HTTPS Bultin Server Main Program TLS and SSI

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/altcp_tls.h"

#include "lwip/apps/httpd.h"
#include "hardware/structs/rosc.h"

#include "hardware/rtc.h"
#include "time.h"

#include "setupWifi.h"

#define BUF_SIZE 2048





void getDateNow(struct tm *t)
{
    datetime_t rtc;
    rtc_get_datetime(&rtc);

    t->tm_sec = rtc.sec;
    t->tm_min = rtc.min;
    t->tm_hour = rtc.hour;
    t->tm_mday = rtc.day;
    t->tm_mon = rtc.month - 1;
    t->tm_year = rtc.year - 1900;
    t->tm_wday = rtc.dotw;
    t->tm_yday = 0;
    t->tm_isdst = -1;
}

void setRTC()
{
    datetime_t t = {
        .year = 2023,
        .month = 02,
        .day = 05,
        .dotw = 0,
        .hour = 6,
        .min = 14,
        .sec = 00};
    rtc_init();
    rtc_set_datetime(&t);
}

const char *ssitags[] = {"temp", "hum"};

u16_t mySSIHandler(int iIndex, char *pcInsert, int iInsertLen)
{
    switch(iIndex){
        case 0:
            snprintf(pcInsert, iInsertLen, "42 C");
            break;
        case 1:
            snprintf(pcInsert, iInsertLen, "80%%");
            break;
    }
}

int main()
{
    stdio_init_all();
    setRTC();
    connect();


    u8_t key[] = {0x30, 0x82, 0x04, 0xbd, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, 0x04, 0xa7, 0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, 0x00, 0x1e, 0x04, 0x4b, 0xc5, 0xa4, 0xa0, 0x8b, 0x1a, 0xfd, 0x3d, 0xbb, 0xce, 0x74, 0x6d, 0xdc, 0x8a, 0xc4, 0x8a, 0x7b, 0x49, 0xae, 0x98, 0xc8, 0xf2, 0xbc, 0xae, 0xd4, 0xd8, 0xa4, 0x61, 0x14, 0x03, 0x2c, 0xd9, 0xea, 0xb6, 0xae, 0xe5, 0xbc, 0xc8, 0x35, 0x11, 0x04, 0x9c, 0x41, 0xc2, 0x47, 0xd4, 0x2c, 0x9c, 0x0c, 0xdc, 0x1f, 0x8f, 0xc5, 0xa9, 0xd7, 0xb8, 0xd1, 0xb4, 0x12, 0xf2, 0x44, 0x71, 0x22, 0x69, 0x83, 0x47, 0x84, 0x04, 0x8c, 0x23, 0x37, 0x98, 0xf0, 0xbe, 0x7a, 0x67, 0x48, 0xd7, 0x32, 0xd2, 0xf5, 0x8d, 0xf1, 0xf1, 0x6e, 0xf4, 0x4b, 0xa5, 0x48, 0x1c, 0xcc, 0x7d, 0xe0, 0xa9, 0xee, 0x9d, 0xf3, 0x39, 0x77, 0x64, 0x91, 0x07, 0x70, 0x27, 0xf0, 0x34, 0xa2, 0x21, 0xd8, 0xec, 0xd0, 0xe7, 0xeb, 0x43, 0xc3, 0x6a, 0x20, 0x23, 0x10, 0xfe, 0x42, 0x02, 0x6b, 0xda, 0x89, 0xf4, 0x41, 0x96, 0x64, 0x32, 0x52, 0x20, 0x05, 0x0d, 0x5b, 0xf3, 0x67, 0x51, 0xb7, 0x7d, 0xd1, 0x24, 0x0b, 0x2c, 0x33, 0x84, 0x5b, 0xf9, 0xed, 0x66, 0xe6, 0x3c, 0x4d, 0xdf, 0x09, 0x3e, 0xd5, 0xe5, 0x1c, 0x27, 0x2c, 0x81, 0xee, 0x03, 0x91, 0x8d, 0xc0, 0x2b, 0x3e, 0xd9, 0x37, 0x8e, 0x3d, 0xd1, 0x30, 0xd6, 0x97, 0x7b, 0x98, 0xfb, 0x80, 0x13, 0x5a, 0x84, 0x08, 0x90, 0x0d, 0x5c, 0x99, 0x51, 0x4f, 0x8f, 0xab, 0x0c, 0x39, 0x69, 0x76, 0xf8, 0xf4, 0xfd, 0xa7, 0x04, 0x8d, 0x72, 0x27, 0xa6, 0x1e, 0xbd, 0xff, 0x10, 0x43, 0xe8, 0x53, 0xe7, 0x08, 0xb8, 0xbd, 0x55, 0xb4, 0x7a, 0xa2, 0x44, 0xe9, 0xe7, 0x78, 0xf7, 0x11, 0x49, 0x01, 0x70, 0x60, 0xdf, 0xe8, 0xd1, 0xb0, 0x8c, 0xa2, 0x3d, 0x98, 0x07, 0x9b, 0x66, 0xff, 0xe8, 0x68, 0x33, 0x82, 0xe3, 0x75, 0x3d, 0x37, 0x8d, 0xf2, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe8, 0xc0, 0x12, 0x7f, 0x02, 0x98, 0x75, 0x23, 0xa6, 0x32, 0x92, 0x4e, 0x11, 0x27, 0xad, 0xda, 0x5b, 0x9e, 0xec, 0x9c, 0xa4, 0xb4, 0x26, 0x2b, 0x2b, 0xd4, 0xdb, 0x1a, 0x9e, 0xd5, 0xd3, 0xa8, 0xb4, 0x29, 0x58, 0x79, 0x96, 0x9f, 0x1a, 0xff, 0xdc, 0xef, 0x4c, 0xb3, 0x1b, 0x79, 0x36, 0xd3, 0x03, 0x4d, 0x08, 0x15, 0x54, 0xa7, 0x84, 0x2d, 0xc3, 0xb2, 0x44, 0x75, 0x15, 0x9f, 0x57, 0xae, 0x25, 0x64, 0xcc, 0x5f, 0xdf, 0x7d, 0xd3, 0xe9, 0xb7, 0xbc, 0xeb, 0x01, 0x92, 0xda, 0x9f, 0x7e, 0xc3, 0xc6, 0xce, 0xd9, 0xc2, 0x16, 0x5a, 0x52, 0x0c, 0x1e, 0xe2, 0x92, 0x4a, 0xf2, 0x33, 0x13, 0x78, 0x5f, 0xa3, 0xa8, 0x0d, 0x99, 0x75, 0x8d, 0x33, 0xd5, 0x71, 0xc6, 0x3c, 0x86, 0xf9, 0x36, 0xbf, 0x86, 0x2e, 0xc3, 0xfe, 0x63, 0x7d, 0x50, 0x94, 0xb6, 0x71, 0x7f, 0x9f, 0xb6, 0x55, 0xa5, 0x02, 0x81, 0x81, 0x00, 0xd0, 0xa6, 0xcd, 0xaf, 0x92, 0x3b, 0x7a, 0x2f, 0x17, 0xfd, 0xd1, 0x05, 0x6b, 0x9c, 0x95, 0xb7, 0x7b, 0x39, 0x0c, 0xa5, 0xde, 0xb1, 0xa4, 0x86, 0x87, 0x39, 0x73, 0xb0, 0x22, 0xb3, 0x7c, 0x6a, 0x14, 0xdc, 0x19, 0x98, 0xa7, 0xe7, 0x02, 0xdb, 0x54, 0xa0, 0xc3, 0xbc, 0x80, 0x54, 0x60, 0xb6, 0xa6, 0xf4, 0xc5, 0x01, 0xe1, 0xc3, 0xf7, 0xc3, 0xd2, 0xdb, 0xe7, 0x1f, 0xc9, 0xcc, 0x51, 0x66, 0x66, 0xd0, 0xce, 0x31, 0x5a, 0x31, 0x76, 0xb7, 0x98, 0x52, 0xda, 0x82, 0xe8, 0x33, 0xc8, 0xf0, 0x1a, 0x8f, 0x95, 0x46, 0x7f, 0x48, 0x72, 0x47, 0x1e, 0x33, 0x3c, 0x0f, 0xd7, 0x55, 0x21, 0xc3, 0xea, 0x10, 0x8e, 0xae, 0xbc, 0x18, 0xa5, 0xcc, 0x85, 0xf1, 0x09, 0x3d, 0x15, 0x82, 0xa0, 0x49, 0x55, 0xd6, 0x7f, 0x64, 0xe0, 0xb0, 0xf0, 0x17, 0x75, 0xbd, 0x92, 0xc7, 0x83, 0xe3, 0x59, 0x09, 0x02, 0x81, 0x81, 0x00, 0x88, 0x6b, 0xd4, 0x2b, 0x87, 0xcc, 0xee, 0x93, 0xe7, 0x9d, 0x2a, 0xae, 0x01, 0x56, 0x1d, 0x8b, 0xa8, 0x3a, 0x1d, 0x7b, 0xae, 0xfa, 0x3c, 0x88, 0xff, 0x56, 0xf2, 0xd9, 0xc6, 0x91, 0x94, 0x4f, 0x04, 0xd2, 0x5b, 0x1e, 0x61, 0x4f, 0x7e, 0x96, 0xcb, 0xdb, 0xa3, 0x3c, 0x33, 0xf5, 0x37, 0x52, 0x35, 0x54, 0x18, 0x51, 0xd0, 0x5d, 0xa3, 0x96, 0xe3, 0x66, 0x80, 0xc3, 0x93, 0xd9, 0xe2, 0x9d, 0x9b, 0x23, 0x5a, 0xbb, 0x33, 0x16, 0xe0, 0x77, 0xd4, 0x0f, 0x32, 0x3b, 0xa8, 0xe4, 0xe5, 0xa9, 0x7a, 0x7c, 0xf3, 0xcf, 0x24, 0xf8, 0xcf, 0x15, 0xda, 0x2e, 0xdc, 0x24, 0x5d, 0x33, 0x5b, 0x06, 0xa5, 0x7e, 0x81, 0x41, 0x46, 0x3f, 0x55, 0x6c, 0x5f, 0x1e, 0x53, 0x62, 0x9b, 0x25, 0x8d, 0xbb, 0x2e, 0x45, 0x2a, 0xf2, 0x0c, 0x10, 0x2a, 0x6a, 0x69, 0xd0, 0x09, 0xf4, 0x81, 0x1b, 0x71, 0x55, 0x02, 0x81, 0x80, 0x66, 0x63, 0x74, 0x4b, 0xd3, 0xd6, 0x9b, 0xfe, 0xc0, 0x27, 0x2d, 0x8b, 0x1b, 0x63, 0x9b, 0x94, 0x8e, 0x43, 0x50, 0x91, 0x94, 0xd6, 0x57, 0x86, 0x2c, 0x95, 0x64, 0xcf, 0xea, 0x37, 0x69, 0xb6, 0x24, 0xc6, 0x5d, 0x49, 0x2c, 0x1b, 0x90, 0xab, 0x50, 0xbc, 0x13, 0x51, 0x4d, 0x28, 0x1a, 0xcd, 0x86, 0xe0, 0x56, 0x4c, 0xb6, 0x1d, 0x14, 0x58, 0x64, 0x00, 0xc5, 0x4a, 0x34, 0x1c, 0xaf, 0x55, 0x30, 0xdf, 0x06, 0x4f, 0xf1, 0x92, 0x94, 0x4f, 0x43, 0xd0, 0x64, 0xaa, 0x18, 0x88, 0x50, 0xf2, 0x82, 0x16, 0x33, 0x8a, 0x84, 0xab, 0x68, 0x68, 0xbd, 0xc9, 0x26, 0x90, 0x1f, 0x7b, 0x07, 0x36, 0xbc, 0x85, 0xa3, 0x7e, 0xdb, 0x8e, 0xbc, 0xcd, 0xc0, 0x6c, 0xa7, 0xbb, 0xf1, 0xf2, 0x47, 0xf5, 0xb4, 0xc9, 0xad, 0x7a, 0x33, 0x48, 0xa0, 0x88, 0xe2, 0x9e, 0x44, 0x88, 0xe3, 0x8f, 0x8d, 0x01, 0x02, 0x81, 0x80, 0x04, 0xa3, 0xe0, 0xb3, 0x7e, 0xdd, 0x12, 0x94, 0x27, 0xb0, 0xac, 0x4b, 0x26, 0xfd, 0xb2, 0x5f, 0x2b, 0x91, 0x29, 0x5a, 0x0b, 0x2b, 0x9a, 0xeb, 0x08, 0x21, 0xde, 0x15, 0x79, 0x8a, 0x55, 0x0c, 0xec, 0xac, 0x85, 0x72, 0x11, 0xb6, 0x1d, 0x51, 0xf1, 0xa6, 0x28, 0xa0, 0x86, 0xae, 0x23, 0x7c, 0x4c, 0x2c, 0xfe, 0xce, 0xd4, 0xd3, 0xf2, 0x67, 0x47, 0x6c, 0xa7, 0xfd, 0xe6, 0x80, 0x4f, 0x8d, 0x54, 0xa9, 0x8a, 0xb8, 0x80, 0xc5, 0xbc, 0x6b, 0x7e, 0xe1, 0xc2, 0xa1, 0x24, 0xcf, 0x2d, 0xe1, 0x0c, 0x9f, 0x7b, 0x71, 0xcf, 0x75, 0xb2, 0x04, 0xf8, 0x51, 0xac, 0x07, 0x10, 0x56, 0x93, 0x46, 0x92, 0xdd, 0x1d, 0x5b, 0x1f, 0x94, 0x87, 0xcf, 0xe2, 0x99, 0x36, 0x89, 0xe7, 0xc2, 0x8a, 0x0a, 0x9e, 0x0d, 0x30, 0x17, 0xd5, 0x6d, 0xde, 0x10, 0x94, 0x47, 0x35, 0x89, 0x10, 0xe6, 0x8c, 0x0e};
    u8_t cert[] = {0x30, 0x82, 0x03, 0x6b, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x72, 0x8e, 0xfd, 0x0e, 0x52, 0x0a, 0x87, 0xdd, 0x55, 0x25, 0xee, 0x05, 0x11, 0x1d, 0x0d, 0xf7, 0xc8, 0x64, 0x5b, 0xa0, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x32, 0x30, 0x36, 0x31, 0x35, 0x30, 0x39, 0x35, 0x34, 0x5a, 0x30, 0x45, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x41, 0x55, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x49, 0x4f, 0x20, 0x50, 0x72, 0x65, 0x73, 0x73, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 0x50, 0x69, 0x63, 0x6f, 0x57, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xbd, 0xb3, 0xb6, 0x94, 0x9f, 0x87, 0x85, 0xd6, 0xd4, 0xd0, 0xf9, 0x24, 0x4b, 0x8c, 0x7d, 0x9e, 0xf5, 0x83, 0xac, 0x90, 0x37, 0x5b, 0xdf, 0x4d, 0x9b, 0x05, 0x6b, 0x5f, 0xaa, 0x87, 0x31, 0x87, 0x0e, 0x97, 0x90, 0xa0, 0xff, 0x12, 0x81, 0xcc, 0xfe, 0x66, 0xa3, 0x8e, 0x34, 0x33, 0x63, 0x27, 0x10, 0xa4, 0xf1, 0x57, 0x27, 0x72, 0x54, 0x45, 0x41, 0x62, 0xee, 0x00, 0x36, 0xaa, 0x1f, 0xfa, 0xa3, 0xb0, 0x27, 0xeb, 0x3e, 0xf3, 0xcf, 0x04, 0x17, 0x68, 0x22, 0xf1, 0x1e, 0x1c, 0x9e, 0x27, 0x7d, 0x82, 0xb3, 0x3f, 0x3c, 0x12, 0x63, 0x94, 0x3b, 0xae, 0x87, 0x3c, 0x33, 0x6a, 0x08, 0x63, 0x84, 0xc2, 0xf8, 0x87, 0xbd, 0xfd, 0x25, 0x92, 0xb7, 0x8d, 0xdb, 0xac, 0xe9, 0xcb, 0x3f, 0x04, 0x3d, 0xee, 0x9f, 0xf6, 0x17, 0xbe, 0xea, 0x41, 0x7f, 0x2b, 0x2d, 0x4a, 0xbf, 0x64, 0xea, 0x01, 0x83, 0xf2, 0x59, 0x82, 0x6c, 0xcb, 0x6c, 0x1f, 0x91, 0x53, 0xde, 0x8a, 0x36, 0x7f, 0x41, 0x7e, 0x19, 0x02, 0x80, 0x42, 0x8c, 0xd5, 0xc1, 0x3c, 0x22, 0x06, 0xf4, 0x2d, 0x09, 0x45, 0xbf, 0xc1, 0x12, 0xe3, 0xfc, 0xa3, 0xc2, 0x89, 0x11, 0x7f, 0x01, 0xcb, 0x49, 0xab, 0xc1, 0x50, 0x37, 0xca, 0x03, 0xb7, 0x44, 0x94, 0x16, 0xbf, 0xd6, 0xf5, 0xa6, 0xbc, 0x10, 0x86, 0xf2, 0x97, 0xea, 0x66, 0x15, 0xa3, 0x9f, 0x4d, 0xf0, 0xe6, 0xa5, 0xfb, 0x1f, 0x25, 0xd7, 0x71, 0xed, 0x85, 0x53, 0x5b, 0x86, 0x1c, 0x46, 0x29, 0xb5, 0xa8, 0xa8, 0x25, 0x27, 0x5a, 0x51, 0x27, 0x30, 0xa7, 0x94, 0x07, 0x21, 0xf7, 0x66, 0xe2, 0xab, 0x16, 0x0e, 0x59, 0xa2, 0x7a, 0x70, 0x30, 0xba, 0x6b, 0x9f, 0xf9, 0x4d, 0x22, 0x4e, 0xa3, 0x33, 0x7e, 0x49, 0x43, 0x62, 0x29, 0xf5, 0xc7, 0x61, 0x7e, 0x5f, 0xcd, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x93, 0xc8, 0x8f, 0xac, 0x37, 0x01, 0x7e, 0x4d, 0xd2, 0x87, 0x7a, 0xb5, 0x26, 0xba, 0xd1, 0xa6, 0x1a, 0xcd, 0xd1, 0xb2, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5b, 0x91, 0x51, 0xe1, 0x89, 0x20, 0xf5, 0xdf, 0x02, 0x94, 0x59, 0x76, 0x9e, 0xdc, 0x53, 0xf3, 0x17, 0x8f, 0x96, 0x17, 0xd1, 0x2f, 0x65, 0x36, 0xd4, 0x56, 0x7e, 0xd8, 0x0d, 0x7e, 0x59, 0x79, 0xab, 0x47, 0x67, 0x01, 0xb6, 0x9e, 0xf6, 0x7a, 0x0d, 0x20, 0xd2, 0xb2, 0x2d, 0x87, 0x84, 0x07, 0x40, 0x2d, 0x83, 0x1e, 0x16, 0x4f, 0x2d, 0x20, 0xaf, 0xf2, 0xca, 0xde, 0x10, 0x73, 0x41, 0xb9, 0x48, 0x3c, 0x4f, 0x9d, 0x55, 0xbc, 0xee, 0x68, 0xae, 0x66, 0x4d, 0x5d, 0x41, 0xa9, 0xbc, 0x51, 0x6d, 0xe2, 0x37, 0x0c, 0x0f, 0xf4, 0x43, 0xa0, 0x84, 0xf9, 0x40, 0xbc, 0x89, 0xaa, 0xcd, 0x14, 0xb4, 0xd5, 0xda, 0xd1, 0xb3, 0x2c, 0x4a, 0x56, 0x7e, 0x86, 0x2c, 0x71, 0xaa, 0x75, 0x86, 0x48, 0x14, 0x2a, 0xbc, 0x05, 0xab, 0x14, 0x72, 0x72, 0x01, 0xc8, 0xff, 0x02, 0x3d, 0x2e, 0xe9, 0xef, 0x21, 0x4d, 0x71, 0xf3, 0x0c, 0xba, 0x40, 0xfd, 0x9f, 0xb1, 0x40, 0xea, 0x47, 0x65, 0x3d, 0xb7, 0x52, 0xd8, 0xbb, 0x13, 0x30, 0x38, 0xb4, 0x3c, 0xbf, 0x76, 0x06, 0xe2, 0xb3, 0x3f, 0xf7, 0x7b, 0xdd, 0xdf, 0x54, 0x7b, 0x8d, 0x0c, 0x4d, 0x4a, 0x96, 0xcd, 0x14, 0x5c, 0x7d, 0xed, 0xb3, 0x2f, 0xbd, 0x27, 0xc8, 0x52, 0x6e, 0x58, 0x8e, 0x9c, 0x07, 0xa1, 0x52, 0xe2, 0x49, 0x8c, 0x04, 0x3f, 0x84, 0x32, 0x7b, 0xff, 0x5f, 0xf4, 0xf2, 0xdf, 0x3c, 0x73, 0xff, 0x9f, 0x63, 0x0e, 0xe5, 0x7f, 0xdf, 0xa8, 0x7e, 0x4d, 0xf3, 0x29, 0xd8, 0x2b, 0x41, 0x25, 0xbc, 0x73, 0x41, 0x3b, 0x1f, 0x39, 0x64, 0x48, 0x85, 0xe5, 0x66, 0x90, 0x8c, 0xd3, 0x8a, 0xce, 0xdc, 0xb5, 0x0d, 0x93, 0xb0, 0xd0, 0x8a, 0xef, 0x74, 0x8f, 0x28, 0x2f, 0x2c, 0x96, 0x4a, 0x4f, 0xc3, 0xf1, 0xde, 0x25, 0xff, 0xd4};
    struct altcp_tls_config *tls_config = altcp_tls_create_config_server_privkey_cert(key, sizeof(key), NULL, 0, cert, sizeof(cert));
    http_set_ssi_handler(mySSIHandler, ssitags, 2);
    httpd_inits(tls_config);
    while (true)
    {
        sleep_ms(500);
    }
}

Page 151 Simple HTTPS Bultin Server TLS and SSI CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background hardware_rtc pico_lwip_mbedtls pico_mbedtls pico_lwip_http)
pico_add_extra_outputs(main)

Page 151 Full listing not in book

Simple HTTPS Bultin Server LWIPOPTS.H TLS and SSI

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_ALTCP               1
#define LWIP_ALTCP_TLS           1
#define LWIP_ALTCP_TLS_MBEDTLS   1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG  LWIP_DBG_ON
#define TCP_LISTEN_BACKLOG       1



#define HTTPD_ENABLE_HTTPS   1
#undef MEM_SIZE
#define MEM_SIZE                    8000
#define LWIP_HTTPD_SSI   1

#endif /* __LWIPOPTS_H__ */

Page 144 Full listing not in book

Simple HTTPS Bultin Server mbedtls_config.h TLS and SSI

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client and server modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION
#define MBEDTLS_SSL_SRV_C

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"



Chapter 7

Page 157 Simple UDP server

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "setupWifi.h"

int main()
{
    stdio_init_all();
    connect();

    struct udp_pcb *pcb = udp_new();
    udp_bind(pcb, IP_ADDR_ANY, 8080);

    ip_addr_t ip;
    IP4_ADDR(&ip, 192, 168, 11, 101);

    udp_connect(pcb, &ip, 8080);

    char message[] = "Hello UDP World";
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, strlen(message) + 1, PBUF_RAM);

    snprintf(p->payload, strlen(message) + 1, "%s", message);

    err_t er = udp_send(pcb, p);
    pbuf_free(p);
    while (true)
    {
        sleep_ms(500);
    }
}

Page 157 Full listing not in book

Simple UDP server lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define LWIP_DEBUG 1
#endif /* __LWIPOPTS_H__ */

Page 158 Full listing not in book

Simple UDP server Cmakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background)
pico_add_extra_outputs(main)

Page 158 Python UDP Client

import asyncio
class ClientDatagramProtocol(asyncio.DatagramProtocol):
    def datagram_received(self, data, addr):
        message = data.decode("utf8")
        print("Received",message,"from", addr)

async def main():
    loop = asyncio.get_running_loop()
    transport, protocol = await loop.create_datagram_endpoint(
          lambda: ClientDatagramProtocol(),
                    local_addr=('0.0.0.0', 8080))
    await asyncio.sleep(100000)
    transport.close()

asyncio.run(main())

Page 161 Full listing not in book

Simple UDP client

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "setupWifi.h"

#define BUF_SIZE 1024

void recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    char myBuff[BUF_SIZE];
    if (p != NULL)
    {
        printf("recv total %d  this buffer %d next %d \n", p->tot_len, p->len, p->next);
        printf("From %s:%d\n", ipaddr_ntoa(addr), port);
        pbuf_copy_partial(p, myBuff, p->tot_len, 0);
        myBuff[p->tot_len] = 0;
        printf("Buffer= %s\n", myBuff);
        pbuf_free(p);
    }
}

int main()
{
    stdio_init_all();
    connect();

    struct udp_pcb *pcb = udp_new();
    udp_recv(pcb, recv, NULL);

    udp_bind(pcb, IP_ADDR_ANY, 8080);

    //   ip_addr_t ip;
    //  IP4_ADDR(&ip, 192, 168, 11, 101);
    // IP4_ADDR(&ip, 192, 168, 11, 255);
    // udp_connect(pcb, &ip, 8080);

    while (true)
    {
        sleep_ms(500);
    }
}

Page 162 Python UDP Server

import asyncio

async def main():  
    loop = asyncio.get_running_loop()
    transport, protocol = await loop.create_datagram_endpoint(
                             lambda: asyncio.DatagramProtocol(),
                             local_addr=('0.0.0.0',8080))
    data=b"Hello UDP World"
    for i in range(20):
        transport.sendto(data,addr=("192.168.11.255",8080))
        await asyncio.sleep(1)
    transport.close()  
asyncio.run(main())

Chapter 8

Page 176 SNTP RTC main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/pbuf.h"
#include "lwip/udp.h"
#include "setupWifi.h"
#include "hardware/rtc.h"
#include "time.h"
#include "lwip/dns.h"

bool getDateNow(struct tm *t)
{
    datetime_t rtc;
    bool state = rtc_get_datetime(&rtc);
    if (state)
    {

        t->tm_sec = rtc.sec;
        t->tm_min = rtc.min;
        t->tm_hour = rtc.hour;
        t->tm_mday = rtc.day;
        t->tm_mon = rtc.month - 1;
        t->tm_year = rtc.year - 1900;
        t->tm_wday = rtc.dotw;
        t->tm_yday = 0;
        t->tm_isdst = -1;
    }
    return state;
}

void setRTC(struct tm *datetime)
{
    datetime_t t;
    t.year = datetime->tm_year + 1900;
    t.month = datetime->tm_mon + 1;
    t.day = datetime->tm_mday;
    t.dotw = datetime->tm_wday;
    t.hour = datetime->tm_hour;
    t.min = datetime->tm_min;
    t.sec = datetime->tm_sec;
    rtc_init();
    rtc_set_datetime(&t);
}
struct timeStatus
{
    bool ready;
    struct udp_pcb *pcb;
};

void recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port)
{
    struct timeStatus *tstatus = (struct timeStatus *)arg;
    printf("SNTP responded\n");
    if (p != NULL)
    {
        uint8_t seconds_buf[4];
        pbuf_copy_partial(p, seconds_buf, sizeof(seconds_buf), 40);
        uint32_t seconds_since_1900 = seconds_buf[0] << 24 | seconds_buf[1] << 16 | seconds_buf[2] << 8 | seconds_buf[3];
        time_t seconds_since_1970 = seconds_since_1900 - 2208988800;
        struct tm *datetime = gmtime(&seconds_since_1970);
        setRTC(datetime);
        pbuf_free(p);
        udp_remove(pcb);
        tstatus->pcb=NULL;
        tstatus->ready = true;
    }
}

bool pollSNTP(struct timeStatus *tstatus)
{
    if (tstatus == NULL)
        return true;
    if (tstatus->ready)
    {
        free(tstatus);
        tstatus = NULL;
        return true;
    }
    return false;
}

void dns_found(const char *name, const ip_addr_t *ip, void *arg)
{
    struct timeStatus *tstatus = (struct timeStatus *)arg;
    printf("DNS %s\n", ipaddr_ntoa(ip));
    struct udp_pcb *pcb = udp_new();
    tstatus->pcb = pcb;
    udp_recv(pcb, recv, arg);
    udp_bind(pcb, IP_ADDR_ANY, 123);
    udp_connect(pcb, ip, 123);
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 48, PBUF_RAM);
    uint8_t *payload = (uint8_t *)p->payload;
    memset(payload, 0, 48);
    *payload = 0x1b;
    err_t er = udp_send(pcb, p);
    pbuf_free(p);
}

struct timeStatus *getSNTP()
{
    struct timeStatus *tstatus = malloc(sizeof(struct timeStatus));
    tstatus->ready = false;
    tstatus->pcb=NULL;
    ip_addr_t ip;
    cyw43_arch_lwip_begin();
    err_t err = dns_gethostbyname("time.nist.gov", &ip, dns_found, tstatus);
    cyw43_arch_lwip_end();
    if (err == ERR_OK)
    {
        printf("DNS cache %s\n", ipaddr_ntoa(&ip));
        dns_found("", &ip, tstatus);
    }
    return tstatus;
}

void cancelSNTP(struct timeStatus *tstatus)
{
    if (tstatus != NULL)
    {
        udp_remove(tstatus->pcb);
        free(tstatus);
        tstatus = NULL;
        printf("canceled\n");
    }
}

int main()
{
    stdio_init_all();
    connect();

    while (true)
    {
        struct timeStatus *tstatus = getSNTP();
        sleep_ms(500);
        if (pollSNTP(tstatus))
            break;
        cancelSNTP(tstatus);
    }

    while (true)
    {
        struct tm t;
        getDateNow(&t);
        char Date[100];
        strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", &t);
        printf("%s\n", Date);
        sleep_ms(5000);
    }
}

Page 182 SNTP RTC App main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "setupWifi.h"
#include "hardware/rtc.h"
#include <time.h>
#include "lwip/apps/sntp.h"

void SNTPSetRTC(u32_t t, u32_t us)
{
    printf("updating RTC\n");
    time_t seconds_since_1970 = t - 2208988800;
    struct tm *datetime = gmtime(&seconds_since_1970);
    datetime_t dt;
    dt.year = datetime->tm_year + 1900;
    dt.month = datetime->tm_mon + 1;
    dt.day = datetime->tm_mday;
    dt.dotw = datetime->tm_wday;
    dt.hour = datetime->tm_hour;
    dt.min = datetime->tm_min;
    dt.sec = datetime->tm_sec;
    rtc_init();
    rtc_set_datetime(&dt);
}

bool getDateNow(struct tm *t)
{
    datetime_t rtc;
    bool state = rtc_get_datetime(&rtc);
    if (state)
    {
        t->tm_sec = rtc.sec;
        t->tm_min = rtc.min;
        t->tm_hour = rtc.hour;
        t->tm_mday = rtc.day;
        t->tm_mon = rtc.month - 1;
        t->tm_year = rtc.year - 1900;
        t->tm_wday = rtc.dotw;
        t->tm_yday = 0;
        t->tm_isdst = -1;
    }
    return state;
}

int main()
{
    stdio_init_all();
    connect();

    sntp_setoperatingmode(SNTP_OPMODE_POLL);
    sntp_setservername(0, "pool.ntp.org");
    sntp_init();

    while (true)
    {
        struct tm t;
        if (getDateNow(&t))        {
            char Date[100];
            strftime(Date, sizeof(Date), "Date: %a, %d %b %Y %k:%M:%S %Z\r\n", &t);
            printf("%s\n", Date);
        }
        sleep_ms(5000);
    }
}

Page 183 Full listing not in book

SNTP RTC app lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H


// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS                      1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET                 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC             1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC             0
#endif
#define MEM_ALIGNMENT               4
#define MEM_SIZE                    4000
#define MEMP_NUM_TCP_SEG            32
#define MEMP_NUM_ARP_QUEUE          10
#define PBUF_POOL_SIZE              24
#define LWIP_ARP                    1
#define LWIP_ETHERNET               1
#define LWIP_ICMP                   1
#define LWIP_RAW                    1
#define TCP_WND                     (8 * TCP_MSS)
#define TCP_MSS                     1460
#define TCP_SND_BUF                 (8 * TCP_MSS)
#define TCP_SND_QUEUELEN            ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK  1
#define LWIP_NETIF_LINK_CALLBACK    1
#define LWIP_NETIF_HOSTNAME         1
#define LWIP_NETCONN                0
#define MEM_STATS                   0
#define SYS_STATS                   0
#define MEMP_STATS                  0
#define LINK_STATS                  0
// #define ETH_PAD_SIZE                2
#define LWIP_CHKSUM_ALGORITHM       3
#define LWIP_DHCP                   1
#define LWIP_IPV4                   1
#define LWIP_TCP                    1
#define LWIP_UDP                    1
#define LWIP_DNS                    1
#define LWIP_TCP_KEEPALIVE          1
#define LWIP_NETIF_TX_SINGLE_PBUF   1
#define DHCP_DOES_ARP_CHECK         0
#define LWIP_DHCP_DOES_ACD_CHECK    0

#ifndef NDEBUG
#define LWIP_DEBUG                  1
#define LWIP_STATS                  1
#define LWIP_STATS_DISPLAY          1
#endif

#define ETHARP_DEBUG                LWIP_DBG_OFF
#define NETIF_DEBUG                 LWIP_DBG_OFF
#define PBUF_DEBUG                  LWIP_DBG_OFF
#define API_LIB_DEBUG               LWIP_DBG_OFF
#define API_MSG_DEBUG               LWIP_DBG_OFF
#define SOCKETS_DEBUG               LWIP_DBG_OFF
#define ICMP_DEBUG                  LWIP_DBG_OFF
#define INET_DEBUG                  LWIP_DBG_OFF
#define IP_DEBUG                    LWIP_DBG_OFF
#define IP_REASS_DEBUG              LWIP_DBG_OFF
#define RAW_DEBUG                   LWIP_DBG_OFF
#define MEM_DEBUG                   LWIP_DBG_OFF
#define MEMP_DEBUG                  LWIP_DBG_OFF
#define SYS_DEBUG                   LWIP_DBG_OFF
#define TCP_DEBUG                   LWIP_DBG_OFF
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
#define TCP_WND_DEBUG               LWIP_DBG_OFF
#define TCP_FR_DEBUG                LWIP_DBG_OFF
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
#define TCP_RST_DEBUG               LWIP_DBG_OFF
#define UDP_DEBUG                   LWIP_DBG_OFF
#define TCPIP_DEBUG                 LWIP_DBG_OFF
#define PPP_DEBUG                   LWIP_DBG_OFF
#define SLIP_DEBUG                  LWIP_DBG_OFF
#define DHCP_DEBUG                  LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND  16384

#define SNTP_SERVER_DNS              1
#define SNTP_SUPPORT                 1
#define SNTP_UPDATE_DELAY       60*1000

#define SNTP_SET_SYSTEM_TIME_NTP(sec, us) \
 void SNTPSetRTC(u32_t, u32_t); \
  SNTPSetRTC(sec, us)

#define LWIP_DEBUG 1
#endif /* __LWIPOPTS_H__ */

Page 184 Full listing not in book

SNTP RTC app CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_sntp hardware_rtc)
pico_add_extra_outputs(main)

Chapter 9

Page 190 SMTP  main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "setupWifi.h"

#include "lwip/apps/smtp.h"

void mailsent(void *arg, u8_t smtp_result, u16_t srv_err, err_t err)
{
    printf("mail (%p) sent with results: 0x%02x, 0x%04x, 0x%08x\n", arg,
           smtp_result, srv_err, err);
}

int main()
{
    stdio_init_all();
    connect();

    smtp_set_server_addr("iopress.info");
    smtp_set_server_port(25);  
    smtp_set_auth(NULL, NULL);
  smtp_send_mail("This email address is being protected from spambots. You need JavaScript enabled to view it.", "This email address is being protected from spambots. You need JavaScript enabled to view it.", "subject", "body", mailsent, NULL);
    while (true)
    {
        sleep_ms(10);
    }
}

Page 191 Full listing not in book

SMTP  CMakelists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
 main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_smtp)  
pico_add_extra_outputs(main)

Page 192 Full listing not in book

SMTP lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#define LWIP_DEBUG 1
#define SMTP_DEBUG LWIP_DBG_ON

#endif /* __LWIPOPTS_H__ */

Page 193 SMTPS main

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"

#include "setupWifi.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/smtp.h"

void mailsent(void *arg, u8_t smtp_result, u16_t srv_err, err_t err)
{
    printf("mail (%p) sent with results: 0x%02x, 0x%04x, 0x%08x\n", arg,
           smtp_result, srv_err, err);
}

int main()
{
    stdio_init_all();
    connect();
    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    smtp_set_tls_config(tls_config);

    smtp_set_server_addr("smtp.gmail.com");
    smtp_set_server_port(465);
    smtp_set_auth("gmailUSER", "App Password");

    smtp_send_mail("gmailUSER", "email address", "subject", "body", mailsent, NULL);
    while (true)
    {
        sleep_ms(10);
    }
}

Page 194 Full listing not in book

SMTPS mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//EC KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C

/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//ECDHE-RSA-AES256-GCM-SHA384
//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 194 Full listing not in book

SMTPS lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384
#undef MEM_SIZE
#define MEM_SIZE 8000

#define LWIP_ALTCP 1
#define LWIP_ALTCP_TLS 1
#define LWIP_ALTCP_TLS_MBEDTLS 1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_ON
#define SMTP_DEBUG LWIP_DBG_ON

#endif /* __LWIPOPTS_H__ */

Page 194 Full listing not in book

SMTPS CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mbedtls
pico_mbedtls pico_lwip_smtp)
pico_add_extra_outputs(main)



Chapter 10

Page 203 MQTT main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/ip_addr.h"
#include "setupWifi.h"
#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/mqtt.h"

int mqttStatus = 0;

void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
    if (status == MQTT_CONNECT_ACCEPTED)
    {
        mqttStatus = 1;
    }
}

static void pub_request_cb(void *arg, err_t result)
{
    printf("Publish result: %d\n", result);
    mqtt_client_t *client = (mqtt_client_t *)arg;
}

void sub_request_cb(void *arg, err_t result)
{
    printf("Subscribe result: %d\n", result);
    mqttStatus = 2;
}

static void incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
    printf("Topic %s. %d\n", topic, tot_len);
}

static void incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
    char *payload = (char *)data;
    printf("payload\n%.*s\n", len, payload);
}

int main()
{
    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);

    mqtt_client_t *client = mqtt_client_new();

    struct mqtt_connect_client_info_t ci;
    memset(&ci, 0, sizeof(ci));
    ci.client_id = "MyPicoW";
    ci.keep_alive = 10;

    ci.tls_config = tls_config;

    ip_addr_t ip;
    IP4_ADDR(&ip, 137, 135, 83, 217);
    // IP4_ADDR(&ip, 20, 79, 70, 109);

    err_t err = mqtt_client_connect(client, &ip, 8883, mqtt_connection_cb, 0, &ci);

    char payload[] = "Hello MQTT World";
    u8_t qos = 2;
    u8_t retain = 0;
    while (true)
    {
        switch (mqttStatus)
        {
        case 0:
            break;
        case 1:
            mqtt_set_inpub_callback(client, incoming_publish_cb, incoming_data_cb, NULL);
            err = mqtt_subscribe(client, "MyTopic", 1, sub_request_cb, NULL);
            break;

        case 2:
            err = mqtt_publish(client, "MyTopic", payload, strlen(payload), qos, retain, pub_request_cb, client);
            break;
        }
        sleep_ms(2000);
    }
}

Page 205 Full listing not in book

MQTT lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384
#undef MEM_SIZE
#define MEM_SIZE 8000

#define LWIP_ALTCP 1
//#define LWIP_ALTCP_TLS 1
//#define LWIP_ALTCP_TLS_MBEDTLS 1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_ON
#define MQTT_DEBUG LWIP_DBG_ON
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 1)
#define MQTT_REQ_MAX_IN_FLIGHT (5)

#endif /* __LWIPOPTS_H__ */

Page 205 Full listing not in book

MQTT Cmakelist.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mqtt)
pico_add_extra_outputs(main)

Page 205 Full listing not in book

MQTT TLS  main program

#include <stdio.h>

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/ip_addr.h"
#include "setupWifi.h"
#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/mqtt.h"

int mqttStatus = 0;

void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
    if (status == MQTT_CONNECT_ACCEPTED)
    {
        mqttStatus = 1;
    }
}

static void pub_request_cb(void *arg, err_t result)
{
    printf("Publish result: %d\n", result);
    mqtt_client_t *client = (mqtt_client_t *)arg;
}

void sub_request_cb(void *arg, err_t result)
{
    printf("Subscribe result: %d\n", result);
    mqttStatus = 2;
}

static void incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
    printf("Topic %s. %d\n", topic, tot_len);
}

static void incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
    char *payload = (char *)data;
    printf("payload\n%.*s\n", len, payload);
}

int main()
{
    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);

    mqtt_client_t *client = mqtt_client_new();

    struct mqtt_connect_client_info_t ci;
    memset(&ci, 0, sizeof(ci));
    ci.client_id = "MyPicoW";
    ci.keep_alive = 10;

    ci.tls_config = tls_config;

    ip_addr_t ip;
    IP4_ADDR(&ip, 137, 135, 83, 217);
    // IP4_ADDR(&ip, 20, 79, 70, 109);

    err_t err = mqtt_client_connect(client, &ip, 8883, mqtt_connection_cb, 0, &ci);

    char payload[] = "Hello MQTT World";
    u8_t qos = 2;
    u8_t retain = 0;
    while (true)
    {
        switch (mqttStatus)
        {
        case 0:
            break;
        case 1:
            mqtt_set_inpub_callback(client, incoming_publish_cb, incoming_data_cb, NULL);
            err = mqtt_subscribe(client, "MyTopic", 1, sub_request_cb, NULL);
            break;

        case 2:
            err = mqtt_publish(client, "MyTopic", payload, strlen(payload), qos, retain, pub_request_cb, client);
            break;
        }
        sleep_ms(2000);
    }
}

Page 205 Full listing not in book

MQTT TLS lwipopts.h

#ifndef _LWIPOPTS_EXAMPLE_COMMONH_H
#define _LWIPOPTS_EXAMPLE_COMMONH_H

// Common settings used in most of the pico_w examples
// (see https://www.nongnu.org/lwip/2_1_x/group__lwip__opts.html for details)

// allow override in some examples
#ifndef NO_SYS
#define NO_SYS 1
#endif
// allow override in some examples
#ifndef LWIP_SOCKET
#define LWIP_SOCKET 0
#endif
#if PICO_CYW43_ARCH_POLL
#define MEM_LIBC_MALLOC 1
#else
// MEM_LIBC_MALLOC is incompatible with non polling versions
#define MEM_LIBC_MALLOC 0
#endif
#define MEM_ALIGNMENT 4
#define MEM_SIZE 4000
#define MEMP_NUM_TCP_SEG 32
#define MEMP_NUM_ARP_QUEUE 10
#define PBUF_POOL_SIZE 24
#define LWIP_ARP 1
#define LWIP_ETHERNET 1
#define LWIP_ICMP 1
#define LWIP_RAW 1
#define TCP_WND (8 * TCP_MSS)
#define TCP_MSS 1460
#define TCP_SND_BUF (8 * TCP_MSS)
#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1)) / (TCP_MSS))
#define LWIP_NETIF_STATUS_CALLBACK 1
#define LWIP_NETIF_LINK_CALLBACK 1
#define LWIP_NETIF_HOSTNAME 1
#define LWIP_NETCONN 0
#define MEM_STATS 0
#define SYS_STATS 0
#define MEMP_STATS 0
#define LINK_STATS 0
// #define ETH_PAD_SIZE 2
#define LWIP_CHKSUM_ALGORITHM 3
#define LWIP_DHCP 1
#define LWIP_IPV4 1
#define LWIP_TCP 1
#define LWIP_UDP 1
#define LWIP_DNS 1
#define LWIP_TCP_KEEPALIVE 1
#define LWIP_NETIF_TX_SINGLE_PBUF 1
#define DHCP_DOES_ARP_CHECK 0
#define LWIP_DHCP_DOES_ACD_CHECK 0

#ifndef NDEBUG
#define LWIP_DEBUG 1
#define LWIP_STATS 1
#define LWIP_STATS_DISPLAY 1
#endif

#define ETHARP_DEBUG LWIP_DBG_OFF
#define NETIF_DEBUG LWIP_DBG_OFF
#define PBUF_DEBUG LWIP_DBG_OFF
#define API_LIB_DEBUG LWIP_DBG_OFF
#define API_MSG_DEBUG LWIP_DBG_OFF
#define SOCKETS_DEBUG LWIP_DBG_OFF
#define ICMP_DEBUG LWIP_DBG_OFF
#define INET_DEBUG LWIP_DBG_OFF
#define IP_DEBUG LWIP_DBG_OFF
#define IP_REASS_DEBUG LWIP_DBG_OFF
#define RAW_DEBUG LWIP_DBG_OFF
#define MEM_DEBUG LWIP_DBG_OFF
#define MEMP_DEBUG LWIP_DBG_OFF
#define SYS_DEBUG LWIP_DBG_OFF
#define TCP_DEBUG LWIP_DBG_OFF
#define TCP_INPUT_DEBUG LWIP_DBG_OFF
#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF
#define TCP_RTO_DEBUG LWIP_DBG_OFF
#define TCP_CWND_DEBUG LWIP_DBG_OFF
#define TCP_WND_DEBUG LWIP_DBG_OFF
#define TCP_FR_DEBUG LWIP_DBG_OFF
#define TCP_QLEN_DEBUG LWIP_DBG_OFF
#define TCP_RST_DEBUG LWIP_DBG_OFF
#define UDP_DEBUG LWIP_DBG_OFF
#define TCPIP_DEBUG LWIP_DBG_OFF
#define PPP_DEBUG LWIP_DBG_OFF
#define SLIP_DEBUG LWIP_DBG_OFF
#define DHCP_DEBUG LWIP_DBG_OFF

#undef TCP_WND
#define TCP_WND 16384
#undef MEM_SIZE
#define MEM_SIZE 8000

#define LWIP_ALTCP 1
#define LWIP_ALTCP_TLS 1
#define LWIP_ALTCP_TLS_MBEDTLS 1

#define LWIP_DEBUG 1
#define ALTCP_MBEDTLS_DEBUG LWIP_DBG_ON
#define MQTT_DEBUG LWIP_DBG_ON
#define MEMP_NUM_SYS_TIMEOUT (LWIP_NUM_SYS_TIMEOUT_INTERNAL + 1)
#define MQTT_REQ_MAX_IN_FLIGHT (5)

#endif /* __LWIPOPTS_H__ */

Page 205 Full listing not in book

MQTT TLS mbedtls_config.h

//Hardware config
#define MBEDTLS_NO_PLATFORM_ENTROPY
#define MBEDTLS_ENTROPY_HARDWARE_ALT
#define MBEDTLS_HAVE_TIME

//error reporting
#define MBEDTLS_ERROR_C
//used by LwIP
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C

//EC KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED
#define MBEDTLS_ECDH_C
#define MBEDTLS_ECDSA_C
#define MBEDTLS_ECP_C

/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED

//RSA KEY EXCHANGE
#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED
#define MBEDTLS_RSA_C

//general key exchange
#define MBEDTLS_PKCS1_V15
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_PK_C
#define MBEDTLS_PK_PARSE_C

//encryption
#define MBEDTLS_AES_C
#define MBEDTLS_CCM_C
#define MBEDTLS_CIPHER_MODE_CBC
#define MBEDTLS_AES_FEWER_TABLES
#define MBEDTLS_GCM_C

//certs
#define MBEDTLS_X509_CRT_PARSE_C
#define MBEDTLS_X509_USE_C
#define MBEDTLS_OID_C
#define MBEDTLS_ASN1_PARSE_C
#define MBEDTLS_ASN1_WRITE_C

//hash methods
#define MBEDTLS_SHA1_C
#define MBEDTLS_SHA224_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_SHA512_C

//ECDHE-RSA-AES256-GCM-SHA384
//TLS
#define MBEDTLS_CIPHER_C
#define MBEDTLS_SSL_TLS_C
#define MBEDTLS_MD_C

//enable client modes and TLS
#define MBEDTLS_SSL_CLI_C
#define MBEDTLS_SSL_SERVER_NAME_INDICATION

//enable TLS 1.2
#define MBEDTLS_SSL_PROTO_TLS1_2

#include "/home/pi/pico/pico-sdk/lib/mbedtls/include/mbedtls/check_config.h"

Page 205 Full listing not in book

MQTT TLS CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
set(PICO_BOARD pico_w)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

include(pico_sdk_import.cmake)
project(PicoW C CXX ASM)
pico_sdk_init()

add_executable(main
main.c
)

target_include_directories(main PRIVATE ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(main pico_stdlib pico_cyw43_arch_lwip_threadsafe_background pico_lwip_mqtt pico_lwip_mbedtls
pico_mbedtls)
pico_add_extra_outputs(main)

Page 207  MQTT HiveMQ main program Note works with modified mqtt.h and mqtt.c

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include "lwip/ip_addr.h"
#include "setupWifi.h"
#include "lwip/altcp.h"
#include "lwip/altcp_tls.h"
#include "lwip/apps/mqtt.h"

int mqttStatus = 0;

void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
    if (status == MQTT_CONNECT_ACCEPTED)
    {
        mqttStatus = 1;
    }
}

static void pub_request_cb(void *arg, err_t result)
{
    printf("Publish result: %d\n", result);
    mqtt_client_t *client = (mqtt_client_t *)arg;
}

void sub_request_cb(void *arg, err_t result)
{
    printf("Subscribe result: %d\n", result);
    mqttStatus = 2;
}

static void incoming_publish_cb(void *arg, const char *topic, u32_t tot_len)
{
    printf("Topic %s. %d\n", topic, tot_len);
}

static void incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
    char *payload = (char *)data;
    printf("payload\n%.*s\n", len, payload);
}

int main()
{
    stdio_init_all();
    connect();

    struct altcp_tls_config *tls_config = altcp_tls_create_config_client(NULL, 0);
    mqtt_client_t *client = mqtt_client_new();

    struct mqtt_connect_client_info_t ci;
    memset(&ci, 0, sizeof(ci));
    ci.client_id = "MyPicoW";
    ci.client_user = "username";
    ci.client_pass = "password";
    ci.keep_alive = 10;
    ci.tls_config = tls_config;
    strncpy(ci.domName, "1a6d2dccd35744888e4b7c6f8e65f613.s2.eu.hivemq.cloud", 100);
    ip_addr_t ip;
    // IP4_ADDR(&ip, 137, 135, 83, 217);
    IP4_ADDR(&ip, 20, 79, 70, 109);

    err_t err = mqtt_client_connect(client, &ip, 8883, mqtt_connection_cb, 0, &ci);

    char payload[] = "Hello MQTT World";
    u8_t qos = 2;
    u8_t retain = 0;
    while (true)
    {
        switch (mqttStatus)
        {
        case 0:
            break;
        case 1:
            mqtt_set_inpub_callback(client, incoming_publish_cb, incoming_data_cb, NULL);
            err = mqtt_subscribe(client, "MyTopic", 1, sub_request_cb, NULL);
            break;

        case 2:
            err = mqtt_publish(client, "MyTopic", payload, strlen(payload), qos, retain, pub_request_cb, client);
            break;
        }
        sleep_ms(2000);
    }
}