//MemoryCAT24.c

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "MemoryCAT24.h"
#include "mcc_generated_files/pin_manager.h"
#include "mcc_generated_files/i2c2.h"
#include "mcc_generated_files/usb/usb_device_cdc.h"

uint8_t CAT_Byte_Address(uint32_t B_address) {
    uint8_t H_Address = CAT_Address | ((B_address >> 16) & 0x01);
    return (H_Address);
}

void CAT_Write_Data(uint32_t address, uint8_t *data, uint16_t Data_Count) {
    if (Data_Count == 0 || Data_Count > 256)
        return;
    uint8_t Mem_Addr = CAT_Byte_Address(address);
    uint16_t Cnt = Data_Count + 2;
    uint8_t AddrHL_Data [260] = {0};
    uint16_t i = 0;
    uint16_t bits_left = 0;
    uint32_t address_up = 0;
    AddrHL_Data [0] = (address & 0xFF00) >> 8;
    AddrHL_Data [1] = (address & 0x00FF);
    bits_left = (0x100 - (address & 0x00FF));
    if (Data_Count <= bits_left) {
        for (i = 0; i < Data_Count; i++) {
            AddrHL_Data [i + 2] = data[i];
        }
        I2C2_Write(AddrHL_Data, Cnt, Mem_Addr);
        __delay_ms(20);
    } else {
        for (i = 0; i < bits_left; i++) {
            AddrHL_Data [i + 2] = data[i];
        }
        Cnt = bits_left + 2;
        I2C2_Write(AddrHL_Data, Cnt, Mem_Addr);
        __delay_ms(20);
        address_up = address + bits_left;
        if (address_up >= 0x20000) {
            address_up = 0;
        }
        Mem_Addr = CAT_Byte_Address(address_up);
        AddrHL_Data [0] = ((address_up) & 0xFF00) >> 8;
        AddrHL_Data [1] = ((address_up) & 0x00FF);
        for (i = 0; i < (Data_Count - bits_left); i++) {
            AddrHL_Data [i + 2] = data[i + bits_left];
        }
        Cnt = Data_Count - bits_left + 2;
        I2C2_Write(AddrHL_Data, Cnt, Mem_Addr);
        __delay_ms(20);
    }
}

void CAT_Read_Data(uint32_t address, uint16_t Data_Count, uint8_t *CAT_Data) {
    uint8_t Mem_Addr = CAT_Byte_Address(address);
    uint8_t AddrHL [2] = {0};
    uint8_t buffer[256] = {};
    AddrHL [0] = (uint8_t)((address  >> 8)& 0xFF);
    AddrHL [1] = (uint8_t)(address & 0xFF);
    I2C2_Write(AddrHL, 2, Mem_Addr);
    
    
    memset(buffer, 0, Data_Count);
    I2C2_Read(buffer, Data_Count, Mem_Addr);
    __delay_ms(10);
    memcpy(CAT_Data, buffer, Data_Count);
}

void CAT_Erase(void) {
    uint32_t i = 0;
    uint8_t Zero_Buff[256] = {};
    for (i = 0; i <= 0x1FF; i++) {
        CAT_Write_Data((i * 0x100), Zero_Buff, 0x80);
        CAT_Write_Data(((i * 0x100)+0x80), Zero_Buff, 0x80);
    }
}