/*
 * ipc_init.c
 *
 *  Created on: 7 нояб. 2023 г.
 *      Author: seklyuts
 */


//
// Included Files

#include "f28x_project.h"
#include "hw_memmap.h"
#include "ipc.h"
#include "flash_programming_f2838x_c28x.h"
#include "internal_flash.h"
#ifdef CPU1
#include <ZD24C02A_Control_Module.h>
#include <ZD24C02A_Power_Module.h>
#include "BL25CM1A.h"
#include "GD25Q16ETIGR.h"
#include "emif_init.h"
#include "spi_init.h"
#include "sysctl.h"
#endif
//#pragma DATA_SECTION(readData, "MSGRAM_CPU_TO_CM")
//uint32_t readData[10];


#define WRONG_COMMAND       0x10
#define ERROR_VERIFY        0x11
#define FLASH_ERR           0x12
#define FLASH_FAIL          0x13
#define FLASH_ECC_FAIL      0x14
#define WRONG_LENGHT        0x15
#define WRONG_ADDR          0x16
#define WRONG_ID            0x17
#define BUSY                0x18

#define COMMAND_ACCEPTED    0x20
#define DONE_SUCCESS        0x21

#define INT_FLASH                       0xA0
#define EMIF                            0xA1
#define BL25CM1A_1M_bit_SPI             0xA2
#define GD25Q16E_16M_bit_SPI            0xA3
#define ZD24C02A_2K_I2C__CONTROL_MODULE 0xA4
#define ZD24C02A_2K_I2C__POWER_MODULE   0xA5
#define FLASH_OTP                       0xA6

typedef enum
{
    READ,
    WRITE,
    VERIFY,
    RESET_NOW,
    END = 0xFF
} Command_Type_t;


uint32_t pass, WriteToCm=0, ReadFromCm=0;

IPC_MessageQueue_t messageQueue;
IPC_Message_t      TxMsg, RxMsg;
uint16_t IntNum = 0;

uint16_t GetMes[16];
uint16_t PutMes[16] = {2,5,6,8,9,4,2,5,4,3,1,6,4,2,8,6};

uint32_t Command, StartAddr, Data;
uint32_t InCommand,InAddr,InData;



uint16_t BlockWasErased[14] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0};

uint16_t * FlashAddress = (uint16_t *)Bzero_Sector0_start;




void putFlashMessage_to_Cm(uint32_t ReadAddress, uint16_t Num)
{
    uint16_t * PutToCmBuff;
    uint16_t i;
    PutToCmBuff = (uint16_t *)CPUXTOCMMSGRAM0_BASE;
    FlashAddress = (uint16_t *)(ReadAddress);
    for(i=0; i < Num; i++)
    {
        PutToCmBuff[i] = FlashAddress[i];
    }
}


uint16_t verifyFlashMessage_to_Cm(uint32_t ReadAddress, uint16_t Num)
{
    uint16_t * GetFromCmBuff;
    uint16_t i, Err = 0;
    GetFromCmBuff = (uint16_t *)CMTOCPUXMSGRAM0_BASE;
    FlashAddress = (uint16_t *)(ReadAddress);
    for(i=0; i < Num; i++)
    {
        if(GetFromCmBuff[i] != FlashAddress[i]) Err++;
    }
    return Err;
}


void clear_BlockWasErased(void)
{
    uint16_t i;
    for(i=0; i < 14; i++)
    {
        BlockWasErased[i] = 0;
    }
}

//#define Internal_flash_Program          Internal_flash_Program_DataOnlyECCOnly
#define Internal_flash_Program          Internal_flash_Program_AutoECC

static const uint32_t FLASH_OTP_START_ADDRESS = 0x00078008;
static const uint32_t FLASH_OTP_MAX_SIZE_IN_BYTES = 0x10;
static const uint32_t IPC_MESSAGE_MEMORY_SIZE_IN_BYTES = 2048;

void getMessage_from_Cm_Flash_OTP(void){
    if((InData & 1)||(InAddr & 1))  {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, FLASH_OTP, 0, 0); return;}

    InData /= 2;
    InAddr /= 2;
    if((InData > IPC_MESSAGE_MEMORY_SIZE_IN_BYTES)||(InData > FLASH_OTP_MAX_SIZE_IN_BYTES)||(InData == 0)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_LENGHT, FLASH_OTP, 0, 0); return;}
    if((InAddr+InData) > FLASH_OTP_START_ADDRESS) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, FLASH_OTP, 0, 0); return;}

    uint32_t FactAddressFlash = InAddr + FLASH_OTP_START_ADDRESS;

    uint16_t MemOperationError = 0;

    switch(InCommand >> 16)
    {
        case READ:
            putFlashMessage_to_Cm(FactAddressFlash, InData);
            IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, FLASH_OTP, 0, 0);
            break;
        case WRITE:
            MemOperationError = Internal_flash_Program(FactAddressFlash, InData);
            if(MemOperationError) {IPC_sendCommand(IPC_CPU1_L_CM_R, MemOperationError, FLASH_OTP, 0, 0); return;}

            IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, FLASH_OTP, 0, 0);
            break;
        case VERIFY:
            MemOperationError = verifyFlashMessage_to_Cm(FactAddressFlash, InData);
            if(MemOperationError) IPC_sendCommand(IPC_CPU1_L_CM_R, ERROR_VERIFY, INT_FLASH, MemOperationError, 0);
            else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, FLASH_OTP, 0, 0);
            break;
        case END:
            IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, FLASH_OTP, 0, 0);
            break;
        default:
            IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_COMMAND, FLASH_OTP, 0, 0);
            break;
        }
}

void getMessage_from_Cm_Flash(void)
{
    uint16_t FlashSektorStart = 0;
    uint16_t FlashSektorEnd = 0;
    uint32_t FactAddressFlash = Bzero_Sector0_start;
    uint32_t block1, block2;
    uint16_t MemOperationError = 0;

    if((InData & 1)||(InAddr & 1))  {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, INT_FLASH, 0, 0); return;}
    InData /= 2;
    InAddr /= 2;
    if((InData > 2048)||(InData == 0)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_LENGHT, INT_FLASH, 0, 0); return;}
    if((InAddr+InData) > 0x40000) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, INT_FLASH, 0, 0); return;}
    IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, INT_FLASH, 0, 0);

    FactAddressFlash = InAddr + Bzero_Sector0_start;

    switch(InCommand >> 16)
    {
    case READ:
        putFlashMessage_to_Cm(FactAddressFlash, InData);
        IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, INT_FLASH, 0, 0);
        break;
    case WRITE:
        FlashSektorStart = Internal_flash_Sektor_Addr(FactAddressFlash); //сектор с которого начинается запись
        FlashSektorEnd = Internal_flash_Sektor_Addr(FactAddressFlash + InData - 1); //сектор в котором конец записи (тот же или следующий, так как размер сектора больше размера буфера)
        if(!BlockWasErased[FlashSektorStart])
        {
            MemOperationError = Internal_flash_Erase(FactAddressFlash); // если сектор с которого начинаем запись не был стёрт, то стираем его
            if(!MemOperationError) BlockWasErased[FlashSektorStart] = 1;
            else {IPC_sendCommand(IPC_CPU1_L_CM_R, MemOperationError, INT_FLASH, 0, 0); return;}//если ошибка -- отправляем сообщение и завершаем
        }
        if(FlashSektorEnd == FlashSektorStart) //если заканчиваем в этом же секторе что и начали, то просто пишем его
        {
            MemOperationError = Internal_flash_Program(FactAddressFlash, InData);
            if(MemOperationError) {IPC_sendCommand(IPC_CPU1_L_CM_R, MemOperationError, INT_FLASH, 0, 0); return;}//если ошибка -- отправляем сообщение и завершаем
        }
        else //если начали в одном секторе, а заканчиваем в другом то
        {
                if(!BlockWasErased[FlashSektorEnd])//стираем второй сектор если он не был стёрт ранее
                {
                    MemOperationError = Internal_flash_Erase(FactAddressFlash+InData);
                    if(!MemOperationError)BlockWasErased[FlashSektorEnd] = 1;
                    else {IPC_sendCommand(IPC_CPU1_L_CM_R, MemOperationError, INT_FLASH, 0, 0); return;}//если ошибка -- отправляем сообщение и завершаем
                }
                block1 = internal_flash_FlashBankStartAddr(FlashSektorEnd)-FactAddressFlash;                                //вычисляем размер первого куска
                block2 = InData - block1;                                                                                   //и размер куска для второго сектора
                MemOperationError = Internal_flash_Program(FactAddressFlash, block1);                                                   // и пишем сперва кусок в первый сектор,
                if(MemOperationError) {IPC_sendCommand(IPC_CPU1_L_CM_R, MemOperationError, INT_FLASH, 0, 0); return;}//если ошибка -- отправляем сообщение и завершаем
                MemOperationError = Internal_flash_Program(internal_flash_FlashBankStartAddr(FlashSektorEnd), block2);                  //  потом кусок во второй
                if(MemOperationError) {IPC_sendCommand(IPC_CPU1_L_CM_R, MemOperationError, INT_FLASH, 0, 0); return;}//если ошибка -- отправляем сообщение и завершаем
        }
        IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, INT_FLASH, 0, 0);
        break;
    case VERIFY:
        MemOperationError = verifyFlashMessage_to_Cm(FactAddressFlash, InData);
        if(MemOperationError) IPC_sendCommand(IPC_CPU1_L_CM_R, ERROR_VERIFY, INT_FLASH, MemOperationError, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, INT_FLASH, 0, 0);
        break;
    case END:
        clear_BlockWasErased();
        IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, INT_FLASH, 0, 0);
        break;
    default:
        IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_COMMAND, INT_FLASH, 0, 0);
        break;
    }
}

#ifdef CPU1
void getMessage_from_Cm_EMIF(void)
{
    uint16_t MemOperationError = 0;
    if((InData > 2048)||(InData == 0)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_LENGHT, EMIF, 0, 0); return;}
    if((InAddr+InData) > 0x100000*2) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, EMIF, 0, 0); return;}
    IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, EMIF, 0, 0);

    switch(InCommand >> 16)
    {
    case READ:

        break;
    case WRITE:

        break;
    case VERIFY:

        break;
    case END:
        IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, EMIF, 0, 0);
        break;
    default:
        IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_COMMAND, EMIF, 0, 0);
        break;
    }
}

void getMessage_from_Cm_BL25CM1A(void)
{
    uint16_t MemOperationError = 0;
    if((InData > 2048*2)||(InData == 0)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_LENGHT, BL25CM1A_1M_bit_SPI, 0, 0); return;}
    if( ((InAddr+InData) > (BL25CM1A0_SIZE*2))||((InAddr) > (BL25CM1A0_SIZE*2)) ) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, BL25CM1A_1M_bit_SPI, 0, 0); return;}
    IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, BL25CM1A_1M_bit_SPI, 0, 0);

    spi_TurnOffCS1_GD25Q16E();
    switch(InCommand >> 16)
    {
    case READ:
        Bl25cm1a_read_data(InAddr, InData, (uint16_t *)CPUXTOCMMSGRAM0_BASE);
        IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, BL25CM1A_1M_bit_SPI, 0, 0);
        break;
    case WRITE:
        Bl25cm1a_write_data(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, BL25CM1A_1M_bit_SPI, 0, 0);
        break;
    case VERIFY:
        MemOperationError = Bl25cm1a_verify_data(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        if(MemOperationError) IPC_sendCommand(IPC_CPU1_L_CM_R, ERROR_VERIFY, BL25CM1A_1M_bit_SPI, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, BL25CM1A_1M_bit_SPI, 0, 0);
        break;
    case END:
        IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, BL25CM1A_1M_bit_SPI, 0, 0);
        break;
    default:
        IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_COMMAND, BL25CM1A_1M_bit_SPI, 0, 0);
        break;
    }
}

void getMessage_from_Cm_GD25Q16E(void)
{
    uint16_t MemOperationError = 0;
    uint32_t EndOfAdr = (InAddr+InData);
    if((InData > (2048*2))||(InData == 0)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_LENGHT, GD25Q16E_16M_bit_SPI, 0, 0); return;}
    if( (EndOfAdr > (GD25Q16E_SIZE*2)) || (InAddr > (GD25Q16E_SIZE*2)) )  {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, GD25Q16E_16M_bit_SPI, 0, 0); return;}
    IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, GD25Q16E_16M_bit_SPI, 0, 0);

    Gpio_SPI_CS_BL25CM1A(1);
    spi_TurnOnCS1_GD25Q16E();

    switch(InCommand >> 16)
    {
    case READ:
        MemOperationError = GD25Q16ETIGR_read_data(InAddr, InData, (uint16_t *)CPUXTOCMMSGRAM0_BASE);
        if(MemOperationError) IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, GD25Q16E_16M_bit_SPI, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, GD25Q16E_16M_bit_SPI, 0, 0);
        break;
    case WRITE:
        MemOperationError = GD25Q16ETIGR_write_data(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        if(MemOperationError) IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, GD25Q16E_16M_bit_SPI, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, GD25Q16E_16M_bit_SPI, 0, 0);
        break;
    case VERIFY:
        MemOperationError = GD25Q16ETIGR_verify_data(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        if(MemOperationError) IPC_sendCommand(IPC_CPU1_L_CM_R, ERROR_VERIFY, GD25Q16E_16M_bit_SPI, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, GD25Q16E_16M_bit_SPI, 0, 0);
        break;
    case END:
        IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, GD25Q16E_16M_bit_SPI, 0, 0);
        GD25Q16ETIGR_clean_SectorWasErraised();
        break;
    default:
        IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_COMMAND, GD25Q16E_16M_bit_SPI, 0, 0);
        break;
    }
    spi_TurnOffCS1_GD25Q16E();
}

void getMessage_from_Cm_ZD24C02A_CONTROL_MODULE(void)
{
    uint16_t MemOperationError = 0;
    uint16_t I2CErr = 0;
    if((InData > (2048*2))||(InData == 0)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_LENGHT, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0); return;}
    if((InAddr+InData) > (ZD24C02A_CONTROL_MODULE_SIZE*2)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0); return;}
    IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);

    switch(InCommand >> 16)
    {
    case READ:
        I2CErr = ZD24C02A_ControlModule_read(InAddr, InData, (uint16_t *)CPUXTOCMMSGRAM0_BASE);
        if(I2CErr) IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        break;
    case WRITE:
        I2CErr = ZD24C02A_ControlModule_write(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        if(I2CErr) IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        break;
    case VERIFY:
        MemOperationError = ZD24C02A_ControlModule_verify(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        if(MemOperationError == 2) IPC_sendCommand(IPC_CPU1_L_CM_R, ERROR_VERIFY, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        else if(MemOperationError == 1)  IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        break;
    case END:
        IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        break;
    default:
        IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_COMMAND, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
        break;
    }
}

void getMessage_from_Cm_ZD24C02A_POWER_MODULE(void)
{
    uint16_t MemOperationError = 0;
    uint16_t I2CErr = 0;
    if((InData > (2048*2))||(InData == 0)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_LENGHT, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0); return;}
    if((InAddr+InData) > (ZD24C02A_POWER_MODULE_SIZE*2)) {IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ADDR, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0); return;}
    IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);

    switch(InCommand >> 16)
    {
    case READ:
        I2CErr = ZD24C02A_PowerModule_read(InAddr, InData, (uint16_t *)CPUXTOCMMSGRAM0_BASE);
        if(I2CErr) IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        break;
    case WRITE:
        I2CErr = ZD24C02A_PowerModule_write(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        if(I2CErr) IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        break;
    case VERIFY:
        MemOperationError = ZD24C02A_PowerModule_verify(InAddr, InData, (uint16_t *)CMTOCPUXMSGRAM0_BASE);
        if(MemOperationError == 2) IPC_sendCommand(IPC_CPU1_L_CM_R, ERROR_VERIFY, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        else if(MemOperationError == 1)  IPC_sendCommand(IPC_CPU1_L_CM_R, FLASH_ERR, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        else IPC_sendCommand(IPC_CPU1_L_CM_R, DONE_SUCCESS, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        break;
    case END:
        IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        break;
    default:
        IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_COMMAND, ZD24C02A_2K_I2C__POWER_MODULE, 0, 0);
        break;
    }
}
#endif

__interrupt void IPC_ISR0()
{
    IPC_ackFlagRtoL(IPC_CPU1_L_CM_R, (1<<0));
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP11;
    if(ReadFromCm == 0) ReadFromCm = 1;
    else IPC_sendCommand(IPC_CPU1_L_CM_R, BUSY, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
}


//__interrupt void IPC_ISR1()
//{

//    getMessage_from_Cm();


//    if(WriteToCm != 2)
//    {
        //putMessage_to_Cm();
        //IPC_sendCommand(IPC_CPU1_L_CM_R, 0, 0, Command, Address, Data);
//    }
//    else WriteToCm = 0;
    //
    // Acknowledge the flag
    //
//    IPC_ackFlagRtoL(IPC_CPU1_L_CM_R, (1<<1));
//    PieCtrlRegs.PIEACK.all = PIEACK_GROUP11;
//}


void ipc_init(void)
{
    //
    // Clear any IPC flags if set already
    //
    IPC_clearFlagLtoR(IPC_CPU1_L_CM_R, IPC_FLAG_ALL);

    EALLOW;
    PieVectTable.CMTOCPUXIPC0_INT = &IPC_ISR0;
//    PieVectTable.CMTOCPUXIPC1_INT = &IPC_ISR1;
    EDIS;


    IER |= M_INT11;
    PieCtrlRegs.PIEIER11.bit.INTx9 = 1;
//    PieCtrlRegs.PIEIER11.bit.INTx10 = 1;

    //
    // Initialize message queue
    //
    IPC_initMessageQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_INT1, IPC_INT1);
    IPC_initMessageQueue(IPC_CPU1_L_CM_R, &messageQueue, IPC_INT0, IPC_INT0);
#ifdef CPU1
    GD25Q16ETIGR_clean_SectorWasErraised();
#endif
    clear_BlockWasErased();
}

void ipc_run(void)
{
        if(ReadFromCm == 1)
        {
            ReadFromCm = 2;
            IPC_readCommand(IPC_CPU1_L_CM_R, 0, 0, &InCommand, &InAddr, &InData );
#ifdef CPU1
            if((InCommand >> 16) == RESET_NOW)
            {
//                CpuSysRegs.SIMRESET.all = 0xA5A50002;//bit.XRSn
//                EALLOW;
//                CmConfRegs.CMRESCTL.all = SYSCTL_CMRESCTL_RESET | SYSCTL_REG_KEY;//.bit.RESETSTS = 1;
//                DevCfgRegs.CPU2RESCTL.all =  ((uint32_t)SYSCTL_CPU2RESCTL_RESET |(SYSCTL_REG_KEY & SYSCTL_CPU2RESCTL_KEY_M)); //.bit.RESET = 1;
//                EDIS;
                CpuSysRegs.SIMRESET.all =  ((uint32_t)SYSCTL_REG_KEY | (uint32_t)1);//программный сброс всех контроллеров
                IPC_sendCommand(IPC_CPU1_L_CM_R, COMMAND_ACCEPTED, ZD24C02A_2K_I2C__CONTROL_MODULE, 0, 0);
                IPC_setFlagLtoR(IPC_CPU1_L_CM_R,(1<<0));
                ReadFromCm = 0;
                return;
            }
#endif
            switch(InCommand & 0xFFFF)
            {
            case INT_FLASH:
                getMessage_from_Cm_Flash();
                break;
#ifdef CPU1
            case FLASH_OTP:
                getMessage_from_Cm_Flash_OTP();
                break;
            case EMIF:
                getMessage_from_Cm_EMIF();
                break;
            case BL25CM1A_1M_bit_SPI:
                getMessage_from_Cm_BL25CM1A();
                break;
            case GD25Q16E_16M_bit_SPI:
                getMessage_from_Cm_GD25Q16E();
                break;
            case ZD24C02A_2K_I2C__CONTROL_MODULE:
                getMessage_from_Cm_ZD24C02A_CONTROL_MODULE();
                break;
            case ZD24C02A_2K_I2C__POWER_MODULE:
                getMessage_from_Cm_ZD24C02A_POWER_MODULE();
                break;
#endif
            default:
                IPC_sendCommand(IPC_CPU1_L_CM_R, WRONG_ID, 0, 0, 0);
                break;
            }

            IPC_setFlagLtoR(IPC_CPU1_L_CM_R,(1<<0));
            ReadFromCm = 0;
        }
}

