/**************************************************************************
 *  Calculate Checksum
 **************************************************************************/
void handle_cksm (void)
{
    u32 u4cksum = 0;
    DM_CHKSUM_PACKET cksm = { DM_CHKSUM_PKT_PATN, 0 };

    DM_ENTRY_LOG ();

#if DM_CAL_CKSM_FROM_USB_BUFFER
    print ("<CHKSUM> : USB buffer .. ");
    cksm.chk_sum = dm_ctx.chk_sum;
    print ("0x%x (=%d)\n", cksm.chk_sum, cksm.chk_sum);
#endif

#if DM_CAL_CKSM_FROM_NAND_FLASH
    print ("<CHKSUM> : NAND flash .. ");
    u4cksum = g_boot_dev.dev_chksum_per_file (dm_ctx.img_info.addr_off, dm_ctx.img_info.img_size);
    print ("0x%x (=%d)\n", u4cksum, u4cksum);
#if DM_CAL_CKSM_FROM_USB_BUFFER
    if (u4cksum != cksm.chk_sum)
    {
        print ("ERROR : USB buffer != NAND flash content\n");
        ASSERT (0);
    }
#endif
    cksm.chk_sum = u4cksum;
#endif

    mt_usbtty_putcn (DM_SZ_CHK_SUM_PKT, (u8 *) & cksm, TRUE);
    dm_ctx.dm_status = DM_STATUS_SECT_WAIT_NXT;

    return;
}
//======================================================================
//  check partition table info command
//======================================================================
void check_pt_cmd (void)
{
    DM_ERRCODE_PACKET errp = { DM_ERROR_PKT_PATN, 0 };
    DM_PKT_TYPE pkt_type;
    char buffer[DM_CMD_MAX_SIZE];
    int i;
#ifdef DEBUG
    print ("DM_PARTITION_INFO_PACKET\n");
    print (": pattern %x\n", g_img_dl_pt_info.pattern);
    print (": part_num = %d\n", g_img_dl_pt_info.part_num);
    for (i = 0; i < PART_MAX_COUNT; i++)
    {
        print (": part_info[%d].part_name = %s\n", i, g_img_dl_pt_info.part_info[i].part_name);
        print (": part_info[%d].start_addr = %x\n", i, g_img_dl_pt_info.part_info[i].start_addr);
        print (": part_info[%d].part_len = %x\n", i, g_img_dl_pt_info.part_info[i].part_len);
        print (": part_info[%d].part_visibility = %x\n", i, g_img_dl_pt_info.part_info[i].part_visibility);
        print (": part_info[%d].dl_selected = %x\n", i, g_img_dl_pt_info.part_info[i].dl_selected);
        print ("\n");
    }
#endif    
    //==================================================
    // check if specified partitions can be downloaded
    //==================================================
#if CFG_PMT_SUPPORT
    errp.err_code = new_part_tab ((u8 *) &g_img_dl_pt_info);
#else
    print("%s : PMT is not supported\n", MOD);
    errp.err_code = DM_ERR_OK;
#endif
    mt_usbtty_putcn (DM_SZ_ERR_CODE_PKT, (u8 *) & errp, TRUE);

    if (errp.err_code != DM_ERR_OK)
    {

        print ("\n%s : the specified partitions can not be downloaded, err_code = %d\n", MOD, errp.err_code);
       
        //================================
        // receive REBOOT packet
        //================================
        reset_dm_descriptor ();
        mt_usbtty_getcn (DM_SZ_REBOOT_STR, buffer);
        pkt_type = judge_pkt_type ((const void *) buffer);
        
        if (pkt_type == DM_PKT_REBT)
        {
            //print ("%s : received REBOOT packet\n", MOD);
            dm_ctx.dm_status = DM_STATUS_REBOOT;
        } 
        else   
        {
            //print ("%s : do not received REBOOT packet\n", MOD);
            dm_ctx.dm_status = DM_STATUS_START;
        }
    }
    else
    {
        dm_ctx.dm_status = DM_STATUS_START;
    }
}
/**************************************************************************
 *  Handle Error
 **************************************************************************/
void handle_errp (void)
{
    DM_ERRCODE_PACKET errp = { DM_ERROR_PKT_PATN, 0 };
    DM_ENTRY_LOG ();
    errp.err_code = dm_ctx.dm_err;
    mt_usbtty_putcn (DM_SZ_ERR_CODE_PKT, (u8 *) & errp, TRUE);
    dm_ctx.dm_status = DM_STATUS_SECT_WAIT_NXT; //DM_STATUS_REBOOT;
    return;
}
//======================================================================
//  update partition table 
//======================================================================
void  handle_update (void)
{
    DM_ERRCODE_PACKET errp = { DM_ERROR_PKT_PATN, 0 };

    //==================================================
    // check if specified partitions can be updated
    //==================================================
#if CFG_PMT_SUPPORT    
    errp.err_code = update_part_tab ();
#else
    print("%s : PMT is not supported\n", MOD);
    errp.err_code = DM_ERR_OK;
#endif
    mt_usbtty_putcn (DM_SZ_ERR_CODE_PKT, (u8 *) & errp, TRUE);
    dm_ctx.dm_status = DM_STATUS_SECT_WAIT_NXT;
}    
/**************************************************************************
 *  Allocate Buffer
 **************************************************************************/
u8 * prepare_data_buf (void)
{
#if 1 //CFG_FPGA_PLATFORM
    dm_ctx.data_buf = (u8 *) 0xF00000;
#else
    dm_ctx.data_buf = (u8 *) dm_rx_buf;
#endif 
    if (dm_ctx.data_buf)
        return dm_ctx.data_buf;

    DM_ASSERT (dm_ctx.data_buf);

    {
        DM_ERRCODE_PACKET errp = { DM_ERROR_PKT_PATN, 0 };
        errp.err_code = DM_ERR_NOMEM;   //TODO
        mt_usbtty_putcn (DM_SZ_ERR_CODE_PKT, (u8 *) & errp, TRUE);
        return NULL;
    }
}
/**************************************************************************
 *  Handle Flash Information Sent From Flash Tool
 **************************************************************************/
void handle_pl_info (void)
{
    DM_PL_INFO_PACKET plip = {0};
    DM_ENTRY_LOG ();
    plip.pattern = DM_PL_INFO_PKT_PATN;
    plip.chip = DRV_Reg16 (APHW_CODE);

    // fill _DM_FLASH_INFO according to NAND exported info.         
    plip.flash_info.man_code = nand_maf_id;
    plip.flash_info.dev_id = g_nand_chip.id;
    plip.flash_info.dev_code = nand_dev_id;
    plip.flash_info.dev_size = g_nand_chip.chipsize;
    plip.flash_info.page_size = g_nand_chip.page_size;
    plip.flash_info.spare_size = g_nand_chip.oobsize;

    // fill dm descriptor according to NAND exported info.          
    dm_ctx.block_size = g_nand_chip.erasesize;
    dm_ctx.page_size = g_nand_chip.page_size;
    dm_ctx.spare_size = g_nand_chip.oobsize;

    DM_LOG ("----------------------------------------\n");
    DM_LOG ("g_nand_chip.page_shift    = %x\n", g_nand_chip.page_shift);
    DM_LOG ("g_nand_chip.page_size     = %x\n", g_nand_chip.page_size);
    DM_LOG ("g_nand_chip.ChipID        = %x\n", g_nand_chip.ChipID);
    DM_LOG ("g_nand_chip.chips_name    = %x\n", g_nand_chip.chips_name);
    DM_LOG ("g_nand_chip.chipsize      = %x\n", g_nand_chip.chipsize);
    DM_LOG ("g_nand_chip.erasesize     = %x\n", g_nand_chip.erasesize);
    DM_LOG ("g_nand_chip.mfr           = %x\n", g_nand_chip.mfr);
    DM_LOG ("g_nand_chip.id            = %x\n", g_nand_chip.id);
    DM_LOG ("g_nand_chip.name          = %x\n", g_nand_chip.name);
    DM_LOG ("g_nand_chip.numchips      = %x\n", g_nand_chip.numchips);
    DM_LOG ("g_nand_chip.oobblock      = %x\n", g_nand_chip.oobblock);
    DM_LOG ("g_nand_chip.oobsize       = %x\n", g_nand_chip.oobsize);
    DM_LOG ("g_nand_chip.eccsize       = %x\n", g_nand_chip.eccsize);
    DM_LOG ("g_nand_chip.bus16         = %x\n", g_nand_chip.bus16);
    DM_LOG ("g_nand_chip.nand_ecc_mode = %x\n", g_nand_chip.nand_ecc_mode);
    DM_LOG ("----------------------------------------\n");

    dm_ctx.img_info.pkt_size = dm_ctx.page_size + dm_ctx.spare_size;
    mt_usbtty_putcn (DM_SZ_PL_INFO_PKT, (u8 *) & plip, TRUE);
}
static int usb_send(u8 *buf, u32 len)
{
    mt_usbtty_putcn((int)len, (char*)buf, 0);
    mt_usbtty_flush();
    return 0;
}