初めてのRaspberry Pi Pico ⑭ C言語 CRC-8の計算確認

　通信時のエラーを検知するのにCRCが使われます。たくさんの種類がありますが、センサでは8ビットが使われます。もとはダラスの1-wireで使われていたPolynomialが0x31 (x8 + x5 + x4 + 1)です。ダラスはマキシムに買収されたので、[Wiki](https://ja.wikipedia.org/wiki/%E5%B7%A1%E5%9B%9E%E5%86%97%E9%95%B7%E6%A4%9C%E6%9F%BB)にはCRC-8-Dallas/Maximという名称が書かれています。2020年マキシムはアナログ・デバイセズに買収されたので、名称が変わるかもしれません。

###CRC-8の計算例
　Sensirionの空気品質センサ[SGP40のデータシート](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/9_Gas_Sensors/Sensirion_Gas_Sensors_SGP40_Datasheet.pdf)に、C言語のコードが掲載されているので、Picoで動かして動作を確認しました。センサの使用例は[こちらを参照](https://www.denshi.club/cookbook/arduino/uno/stemmaarduino4step1-3.html)してください。
###プログラム

```cpp
/**
 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 * Copyright (c) 2020 Sensirion SGP40 Data Sheet
 */

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

uint8_t CalcCrc(uint8_t data[2]) {
    uint8_t crc = 0xFF;
    for(int i = 0; i < 2; i++) {
        crc ^= data[i];
        for(uint8_t bit = 8; bit > 0; --bit) {
            if(crc & 0x80) {
                crc = (crc << 1) ^ 0x31u;
            } else {
                crc = (crc << 1);
            }
        }
    }
    return crc;
}

int main() {
    stdio_init_all();
    printf("start \n");
    uint8_t data[2];
    data[0] = 0xff; data[1] = 0xff;
    uint8_t crc8 = CalcCrc(data);
    printf("crc2 %x\n", crc8);
}
```

###動作確認
　動作確認は、http://www.sunshine2k.de/coding/javascript/crc/crc_js.html で行いました。次の画面は、データシートに載っている0xBEEFを入れて、CRCデータ0x92を算出した様子です。

![crc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/c0de020c-1010-8c17-8b00-3f82eeedac1c.png)

###make
　第8回で解説したpico/worksで作業をしています。CRC8というフォルダを作りました。
![pico101.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/19a2084d-bdbc-5b5a-0883-e78d378f53f6.png)

worksの中にあるCMakeLists.txtの内容です。第6回と比べ、不要なinclude(example_auto_set_url.cmake)の行を削除しました。

```shell
cmake_minimum_required(VERSION 3.12)

# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)

project(pico_examples C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

set(PICO_EXAMPLES_PATH ${PROJECT_SOURCE_DIR})

# Initialize the SDK
pico_sdk_init()

# Add blink example
add_subdirectory(blink)
add_subdirectory(cmake)
add_subdirectory(LED7seg_74HC595)
add_subdirectory(bus_scan)
add_subdirectory(lcd_1602_i2c)
add_subdirectory(CRC8)
```
　フォルダCRC8には二つのファイルがあります。ソースcrc8.cは最初に掲載しました。
![pico102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407635/84a491c2-d288-14c5-a892-145ead7fe596.png)

　CMakeLists.txtの内容です。

```shell
add_executable(crc8
        crc8.c
        )

# Pull in our pico_stdlib which pulls in commonly used features
target_link_libraries(crc8 pico_stdlib)

# create map/bin/hex file etc.
pico_add_extra_outputs(crc8)
```

　第6回と比べ、urlの部分をコメントアウトもしくは削除しています。

```
# add url via pico_set_program_url
#example_auto_set_url(ｘｘｘｘｘ)
```

　CRC8のフォルダを作ってその直下のCMakeLists.txtを修正した後、pico/works/buildに降りて、cmake ..を実行します。
　その直下にできたpico/works/build/CRC8へ降りて、make -j4を実行すると、このフォルダ内にcrc8.uf2ができています。
　第6回で作ったResetボタンを使います。Resetボタンを押したまま、BOOTSELボタンを押し、Resetボタンを放してから、BOOTSELボタンを放します。これでRPI-RP2ディスクがマウントができます。これにcrc8.uf2をドロップします。

　その前に、第3回で解説した「標準出力を用意」でターミナルを動かしておきます。このターミナルにCRCの計算結果が出力されます。