

#include <K10_Tiny_ML_inferencing.h>
#include <Wire.h>

// SC7A20H 传感器 I2C 地址
#define SC7A20H_ADDR 0x19 

// 加速度数据寄存器
#define ACC_X_L 0xA8
#define ACC_X_H 0xA9
#define ACC_Y_L 0xAA
#define ACC_Y_H 0xAB
#define ACC_Z_L 0xAC
#define ACC_Z_H 0xAD

// 初始化 SC7A20H
void initSC7A20H() {
    Wire.begin();  // 初始化 I2C
    delay(10);
    
    // 设置 SC7A20H 进入正常工作模式
    Wire.beginTransmission(SC7A20H_ADDR);
    Wire.write(0x20);  // 控制寄存器 1 (CTRL_REG1)
    Wire.write(0x57);  // 100Hz 采样率, 正常模式, 使能 X/Y/Z 轴
    Wire.endTransmission();
}

// 读取 SC7A20H 单个轴的数据
int16_t readAxis(uint8_t regL, uint8_t regH) {
    Wire.beginTransmission(SC7A20H_ADDR);
    Wire.write(regL);
    Wire.endTransmission();
    Wire.requestFrom(SC7A20H_ADDR, 1);
    uint8_t lsb = Wire.read();

    Wire.beginTransmission(SC7A20H_ADDR);
    Wire.write(regH);
    Wire.endTransmission();
    Wire.requestFrom(SC7A20H_ADDR, 1);
    uint8_t msb = Wire.read();

    // 组合高低字节，右移 4 位
    int16_t value = ((msb << 8) | lsb) >> 4;

    // 处理负数（补码转换）
    if (value & 0x800) {
        value -= 4096;
    }

    return value;
}

static float features[] = {
  -47, 145, -1064, -46, 146, -1058, -40, 144, -1058, -39, 144, 
  -1067, -41, 141, -1061, -46, 139, -1056, -46, 139, -1056, -47, 
  141, -1048, -45, 141, -1043, -42, 142, -1048
};


int raw_feature_get_data(size_t offset, size_t length, float *out_ptr) {
    memcpy(out_ptr, features + offset, length * sizeof(float));
    return 0;
}

void print_inference_result(ei_impulse_result_t result);

void setup()
{
    // put your setup code here, to run once:
    Serial.begin(115200);
    // comment out the below line to cancel the wait for USB connection (needed for native USB)
    while (!Serial);
    Serial.println("Edge Impulse Inferencing Demo");

    Wire.begin(47, 48);  // SDA = GPIO47, SCL = GPIO48
    initSC7A20H();
}


void loop()
{

    ei_printf("Edge Impulse standalone inferencing (Arduino)\n");
    for (int i = 0; i < 10; i++) {
    // 读取每个样本的 X, Y, Z 加速度数据
    int accX = readAxis(ACC_X_L, ACC_X_H);
    int accY = readAxis(ACC_Y_L, ACC_Y_H);
    int accZ = readAxis(ACC_Z_L, ACC_Z_H);
    
    // 填充每个样本的三个数据
    features[i * 3] = accX;  // 第 i 组样本的 accX
    features[i * 3 + 1] = accY;  // 第 i 组样本的 accY
    features[i * 3 + 2] = accZ;  // 第 i 组样本的 accZ
    }

    if (sizeof(features) / sizeof(float) != EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE) {
        ei_printf("The size of your 'features' array is not correct. Expected %lu items, but had %lu\n",
            EI_CLASSIFIER_DSP_INPUT_FRAME_SIZE, sizeof(features) / sizeof(float));
        delay(1000);
        return;
    }

    ei_impulse_result_t result = { 0 };

    // the features are stored into flash, and we don't want to load everything into RAM
    signal_t features_signal;
    features_signal.total_length = sizeof(features) / sizeof(features[0]);
    features_signal.get_data = &raw_feature_get_data;

    // invoke the impulse
    EI_IMPULSE_ERROR res = run_classifier(&features_signal, &result, false /* debug */);
    if (res != EI_IMPULSE_OK) {
        ei_printf("ERR: Failed to run classifier (%d)\n", res);
        return;
    }

    // print inference return code
    ei_printf("run_classifier returned: %d\r\n", res);
    print_inference_result(result);

    delay(1000);
}

void print_inference_result(ei_impulse_result_t result) {

    // Print how long it took to perform inference
    ei_printf("Timing: DSP %d ms, inference %d ms, anomaly %d ms\r\n",
            result.timing.dsp,
            result.timing.classification,
            result.timing.anomaly);

    ei_printf("Predictions:\r\n");
    for (uint16_t i = 0; i < EI_CLASSIFIER_LABEL_COUNT; i++) {
        ei_printf("  %s: ", ei_classifier_inferencing_categories[i]);
        ei_printf("%.5f\r\n", result.classification[i].value);
    }

}