#include "system/task_crc.h"
#include "system/data_channel.h"
#include "system/float_word.h"

#define CRC32_POLY 0xEDB88320
#define CRC32_INIT 0xFFFFFFFF
#define DATA_CHANNEL_DEPTH 1024

static uint32_t crc32_update(uint32_t crc, uint32_t data) {
    int i;
    crc ^= data;
    for (i = 0; i < 32; i++) {
        if (crc & 1) {
            crc = (crc >> 1) ^ CRC32_POLY;
        } else {
            crc >>= 1;
        }
    }
    return crc;
}

int task_crc_run(void *task) {
    crc_config *config = (crc_config *)task;
    uint32_t source_base = config->base.sources[0];
    uint32_t sink_base = config->base.sink;
    uint32_t crc = CRC32_INIT;
    uint32_t value;
    
    for (uint32_t i = 0; i < DATA_CHANNEL_DEPTH; i++) {
        data_channel_read(source_base, &value);
        crc = crc32_update(crc, value);
    }
    
    crc ^= 0xFFFFFFFF;
    
    data_channel_write(sink_base, crc);
    
    return 0;
}

