⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lld.c

📁 OMAP1030 处理器的ARM 侧硬件测试代码 OMAP1030 是TI的双核处理器
💻 C
📖 第 1 页 / 共 5 页
字号:

		/* in multi-device configuration */
		switch (data_cfg)
		{
			case X16_AS_X32:	/* drop through */		
			case X8X16_AS_X32:	
				*device_multiplier_ptr = 0x00010001;
				break;

			case X8_AS_X16:			
				*device_multiplier_ptr = 0x0101;
				break;

			case X8_AS_X32:
				*device_multiplier_ptr = 0x01010101;
				break;

			default:
				*err_code_ptr = LLD_E_INVALID_PARAMETER;
				MY_SPRINTF(err_buf, "Invalid data config.\n");
				status = LLD_ERROR;
				break;
		}

		/* break out of for loop */
		break;
	}

	return (status);
}

/******************************************************************************
*    
* lld_StatusGet - Determines Flash Status
*
*
* RETURNS: LLD_OK, or LLD_ERROR
*
* ERRNO:    
*  LLD_E_INTERNAL_ERROR
*  LLD_E_WRITE_BUFFER_LOAD_ERROR;
*  LLD_E_FLASH_INTERNAL_TIMEOUT
*  errors from Init functions
*  errors generated by HAL functions
*/

int lld_StatusGet
   (
    ADDRESS     base_addr,      /* device base address in system */
    DWORD     offset,         /* address offset from base address */
    PARAM       data_cfg,       /* flash data width and # of devices */
    DEVSTATUS*  dev_status_ptr, /* device status */
    FLASHDATA*  act_data_ptr,   /* actual data */
    PARAM       polling_type,   /* type of polling to perform */
    PARAM*      err_code_ptr,   /* variable to store error code */    
    char*       err_buf         /* buffer to store error text */
    )
{
    int status = LLD_OK;

    FLASHDATA    new_data          = 0;
    FLASHDATA    old_data          = 0;
    FLASHDATA    read_mask         = 0;
    FLASHDATA    active_mask       = 0;
    FLASHDATA    toglbit1_mask     = 0;
    FLASHDATA    toglbit2_mask     = 0;
    FLASHDATA    xcdtimelim_mask   = 0;
    FLASHDATA    wrtbufabort_mask  = 0;
    int          flag;


    /* Initialize Masks */
    status = ReadMaskInit(&read_mask, data_cfg, err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    
    /* do the first status read of the device */
    status = HalRead(base_addr + offset, &old_data, 
                     err_code_ptr, err_buf);
    if (status != LLD_OK)
        return (status);

    /* do the second status read of the device */
    status = HalRead(base_addr + offset,    &new_data, 
                     err_code_ptr, err_buf);
    if (status != LLD_OK)
        return (status);
    
    /* Store most recent read data for caller (before clean-up) */
    *act_data_ptr = new_data;
    
    /* clean up data */
    old_data &= read_mask;    
    new_data &= read_mask;    

    /* Check if steady state */
    if (old_data == new_data)            /* If you get the same data   */
    {                                    /* twice, the device has      */
        *dev_status_ptr = dev_not_busy;  /* obviously finished without */
        return (LLD_OK);                 /* without errors.            */
    }
    
    /* Spansion flash devices transition from program and erase        */
    /* operations to reading array data on their own.  While polling,  */
    /* it is common for the first read of status to be status, but     */
    /* the second read is the actual data itself.  Since we must       */
    /* compare the first and second reads together to determine        */
    /* whether toggling is occurring, etc., we have chosen to ignore   */
    /* cases where it appears the first read is status and the         */
    /* second read is data. If we see transitions on DQ7 or DQ5,       */
    /* we exits with a busy return value, assuming things will         */
    /* have settled down by the next set of reads.                     */
    status = AreDevicesInTransition(&flag, old_data, new_data, data_cfg,  
                                    err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    if (flag)
    {
        *dev_status_ptr = dev_busy;
        return (LLD_OK);
    }

    /* At this point, we have two samples of status/data from all     */
    /* the devices interleaved together.  Some devices may be         */
    /* reporting status both times while others may be reporting      */
    /* data both times.                                               */
    /* Create some masks for isolating specific bits.                 */
    status = ToggleBit1MaskInit(&toglbit1_mask, data_cfg, 
                                err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    status = ToggleBit2MaskInit(&toglbit2_mask, data_cfg, 
                                err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    status = ExceedTimeLimitMaskInit(&xcdtimelim_mask, data_cfg, 
                                     err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    status = WrtBufAbortMaskInit(&wrtbufabort_mask, data_cfg, 
                                 err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    /* This is a special mask for isolating only the busy devices. */
    status = ActiveMaskInit(&active_mask, old_data, new_data, data_cfg, polling_type,
                            err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    
    /* check that active devices were identified */
    if (active_mask == 0)
    {
        if (polling_type == LLD_P_POLL_RESUME)
        {
           *dev_status_ptr = dev_not_busy;
           return (LLD_OK);
        }
        else
        {
           *dev_status_ptr = dev_status_unknown;
           *err_code_ptr  = LLD_E_INTERNAL_ERROR;
           return (LLD_ERROR);
        }
    }


    /* mask out inactive (ready) devices */
    old_data &= active_mask;
    new_data &= active_mask;
    
    xcdtimelim_mask  &= active_mask;
    wrtbufabort_mask &= active_mask;
    toglbit1_mask    &= active_mask;
    toglbit2_mask    &= active_mask;

    *dev_status_ptr = dev_status_unknown;


    /* Check if time limits exceeded: 
     * if all active devices have their DQ5 bits == 1 
     * then this is an error condition. 
     */
    if ((new_data & xcdtimelim_mask) == (xcdtimelim_mask))
    {
        *dev_status_ptr = dev_exceeded_time_limits;
        MY_SPRINTF(err_buf, "Internal Time Limits Exceeded.\n");
        *err_code_ptr   = LLD_E_FLASH_INTERNAL_TIMEOUT;
        return (LLD_OK);
    }

    /* check for write buffer abort 
     * Note: if some devices started programming successfully
     *       then this allows them to finish 
     *       Only when all active devices are in write buffer abort state 
     *       will this function return a "write buffer abort" error
     */      
    if (polling_type == LLD_P_POLL_WRT_BUF_PGM)
    {
        if ((new_data & wrtbufabort_mask) == (wrtbufabort_mask))
        {
            *dev_status_ptr  = dev_write_buffer_abort;
            *err_code_ptr    = LLD_E_WRITE_BUFFER_LOAD_ERROR;
            MY_SPRINTF(err_buf, "Write Buffer Load Error.\n");
            return (LLD_OK);
        }
    }

    /* check for suspend: 
     * Toggle Bit 1 has stopped toggling on all active devices
     * AND Toggle Bit 2 is toggling on all active devices 
     */
    if ( ((new_data & toglbit1_mask) == (old_data & toglbit1_mask)) &&
         ((((new_data ^ old_data) & toglbit2_mask) ^ toglbit2_mask) == 0) &&
         (polling_type != LLD_P_POLL_RESUME) )
    {
        *dev_status_ptr = dev_suspend;
        return (LLD_OK);
    }

    /* note: new default return value is busy.  
     *       this removes "undetermined state" check present in old
     *       "status get" function
     */
    *dev_status_ptr = dev_busy;
    return (LLD_OK);
}


/******************************************************************************/
int AreDevicesInTransition(int        *flag_ptr, 
                           FLASHDATA  data1, 
                           FLASHDATA  data2, 
                           PARAM      data_cfg,
                           PARAM      *err_code_ptr,    
                           char       *err_buf            
                           )
{
    int          status = LLD_ERROR;
    FLASHDATA    dev_multiplier;
    FLASHDATA    dq7_dev_mask;
    FLASHDATA    dq5_dev_mask;
    
    status = DeviceMultiplierInit(&dev_multiplier, data_cfg, 
                                  err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    dq7_dev_mask = dev_multiplier * DQ7_BIT_MASK;
    dq5_dev_mask = dev_multiplier * DQ5_BIT_MASK;

    if ((dq7_dev_mask & data1) != (dq7_dev_mask & data2))
    {
        *flag_ptr = TRUE;
        return LLD_OK;
    }
    
    if ((dq5_dev_mask & data1) != (dq5_dev_mask & data2))
    {
        *flag_ptr = TRUE;
        return LLD_OK;
    }

    *flag_ptr = FALSE;
    return LLD_OK;
}


/******************************************************************************/
/* ActiveMaskInit Philosophy:
 *    1.)    identify which devices have DQ6 toggling 
 *        and clean out bits other than DQ6
 *    2.)    identify which devices have DQ2 toggling 
 *        and clean out bits other than DQ2
 *    3.)    Shift the DQ6 bits over to the "DQ0" position (e.g. 0x40 --> 0x01)
 *        and store the result in the "active_mask" variable.
 *    4.)    Shift the DQ2 bits over to the "DQ0" position (e.g. 0x04 --> 0x01) 
 *        (for suspended devices) 
 *        and OR-in the result to the "active_mask" variable.
 *
 *    Example: 
 *  --------
 *    X8_AS_X32 configuration DQ6 toggling on device 0
 *        and DQ2 toggling on device 3:                   0x0200 0040
 *    active mask after DQ6 shift:                        0x0000 0001
 *    active mask after DQ2 shift:                        0x0100 0001
 *    active mask after multiplying by 0xFF:              0xFF00 00FF
 *
 */
int ActiveMaskInit(FLASHDATA* active_mask_ptr, 
                   FLASHDATA  data1, 
                   FLASHDATA  data2, 
                   PARAM      data_cfg,
                   PARAM      polling_type,
                   PARAM*     err_code_ptr,    
                   char*      err_buf            
                   )
{
    FLASHDATA    active_mask_tmp = 0;
    FLASHDATA    read_mask       = 0;
    FLASHDATA    toglbit1_mask   = 0;
    FLASHDATA    toglbit2_mask   = 0;
    FLASHDATA    dq6togl_active  = 0;
    FLASHDATA    dq2togl_active  = 0;
    FLASHDATA    combined_togl_mask  = 0;
    int          status          = LLD_ERROR;


    status = ToggleBit1MaskInit(&toglbit1_mask, data_cfg, 
                                err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;

    status = ToggleBit2MaskInit(&toglbit2_mask, data_cfg, 
                                err_code_ptr, err_buf);
    if (status != LLD_OK)
        return status;
    
    
    dq6togl_active     = (data1 ^ data2) & toglbit1_mask;
    dq2togl_active     = (data1 ^ data2) & toglbit2_mask;
    combined_togl_mask = (data1 ^ data2) & (toglbit1_mask | toglbit2_mask);

    /* when called from lld_EraseResumeCmd, we do not want lld_StatusGet */
    /* to return dev_busy when simply erase suspended.                   */
    if (polling_type == LLD_P_POLL_RESUME)
    {
       /* indirectly determine the number of devices (interleaving) */
       status = ReadMaskInit(&read_mask, data_cfg, err_code_ptr, err_buf);
       if (status != LLD_OK) return status;

       /* determine the size of an individual device */
       switch(GetUnitReadMask(data_cfg))
       {
          case 0xFF:
             switch(read_mask)
                   /* if erase suspended, make it not active */
             {
                case 0xFF:
                   if (combined_togl_mask == toglbit2_mask) dq2togl_active = 0;
                   break;
                case 0xFFFF:
                   if ((combined_togl_mask & 0xFF)   == (toglbit2_mask & 0xFF))   dq2togl_active &= 0xFF00;
                   if ((combined_togl_mask & 0xFF00) == (toglbit2_mask & 0xFF00)) dq2togl_active &= 0x00FF;
                   break;
                case 0xFFFFFFFF:
                   if ((combined_togl_mask & 0x000000FF)   == (toglbit2_mask & 0x000000FF))   dq2togl_active &= 0xFFFFFF00;
                   if ((combined_togl_mask & 0x0000FF00)   == (toglbit2_mask & 0x0000FF00))   dq2togl_active &= 0xFFFF00FF;
                   if ((combined_togl_mask & 0x00FF0000)   == (toglbit2_mask & 0x00FF0000))   dq2togl_active &= 0xFF00FFFF;
                   if ((combined_togl_mask & 0xFF000000)   == (toglbit2_mask & 0xFF000000))   dq2togl_active &= 0x00FFFFFF;
                   break;
             }
             break;
          case 0xFFFF:
             switch(read_mask)
             {
                case 0xFFFF:
                   if (combined_togl_mask == toglbit2_mask) dq2togl_active = 0;
                   break;
                case 0xFFFFFFFF:
                   if ((combined_togl_mask & 0x0000FFFF)   == (toglbit2_mask & 0x0000FFFF))   dq2togl_active &= 0xFFFF0000;
                   if ((com

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -