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

📄 pdo.c

📁 AVR平台下的CanOpen协议桟源码包括应用
💻 C
📖 第 1 页 / 共 2 页
字号:

/* ------------------------------------------------------------------------ */

void rpdo1( BYTE dlc, BYTE *can_data )
{
  /* Receive-PDO1: Digital Outputs */

  digout_pdo( dlc, can_data );
}

/* ------------------------------------------------------------------------ */

void rpdo2( BYTE dlc, BYTE *can_data )
{
  /* Receive-PDO2: Analogue Outputs */

  dac_pdo( dlc, can_data );
}

/* ------------------------------------------------------------------------ */

BOOL pdo_rtr_required( void )
{
  /* Check if any of the transmission types requires CAN Remote Frames */
  BOOL pdo_no;
  BOOL required = FALSE;

  for( pdo_no=0; pdo_no<TPDO_CNT; ++pdo_no )
    {
#ifdef __VARS_IN_EEPROM__
      TPdoCommPar[pdo_no].transmission_type =
	eeprom_read( EE_PDO_TTYPE + pdo_no );
#endif /* __VARS_IN_EEPROM__ */

      /* Only if Transmit-PDO has certain transmission types */
      if( TPdoCommPar[pdo_no].transmission_type >= 253 )
	required = TRUE;
    }

  return required;
}

/* ------------------------------------------------------------------------ */

BOOL tpdo_get_comm_par( BYTE pdo_no,
			BYTE od_subind,
			BYTE *nbytes,
			BYTE *par )
{
  if( pdo_no < TPDO_CNT )
    {
      return( pdo_get_comm_par( pdo_no, od_subind, nbytes, par ) );
    }
  return FALSE;
}

/* ------------------------------------------------------------------------ */

BOOL rpdo_get_comm_par( BYTE pdo_no,
			BYTE od_subind,
			BYTE *nbytes,
			BYTE *par )
{
  if( pdo_no < RPDO_CNT )
    {
      pdo_no += TPDO_CNT;/* RPDO parameters are stored BEHIND the TPDO pars */
      return( pdo_get_comm_par( pdo_no, od_subind, nbytes, par ) );
    }
  return FALSE;
}

/* ------------------------------------------------------------------------ */

BOOL tpdo_get_mapping( BYTE pdo_no,
		       BYTE od_subind,
		       BYTE *nbytes,
		       BYTE *par )
{
  if( pdo_no < TPDO_CNT )
    {
      return( pdo_get_mapping( pdo_no, od_subind, nbytes, par ) );
    }
  return FALSE;
}

/* ------------------------------------------------------------------------ */

BOOL rpdo_get_mapping( BYTE pdo_no,
		       BYTE od_subind,
		       BYTE *nbytes,
		       BYTE *par )
{
  if( pdo_no < RPDO_CNT )
    {
      pdo_no += TPDO_CNT;/* RPDO parameters are stored BEHIND the TPDO pars */
      return( pdo_get_mapping( pdo_no, od_subind, nbytes, par ) );
    }
  return FALSE;
}

/* ------------------------------------------------------------------------ */

BOOL tpdo_set_comm_par( BYTE pdo_no,
			BYTE od_subind,
			BYTE nbytes,
			BYTE *par )
{
  /* If 'nbytes' is zero it means the data set size was
     not indicated in the SDO message */

  if( pdo_no >= TPDO_CNT ) return FALSE;

  switch( od_subind )
    {
    case OD_PDO_TRANSMTYPE:
      if( nbytes == 1 || nbytes == 0 )
	{
	  if( par[0] != 1 && par[0] != 255 ) return FALSE;

	  PdoCommPar[pdo_no].transmission_type = par[0];

#ifdef __VARS_IN_EEPROM__
	  if( eeprom_read(EE_PDO_TTYPE+pdo_no) !=
	      PdoCommPar[pdo_no].transmission_type )
	    eeprom_write( EE_PDO_TTYPE+pdo_no,
			  PdoCommPar[pdo_no].transmission_type );
#endif /* __VARS_IN_EEPROM__ */

	  /* Adjust CAN-controller configuration if necessary */
	  can_rtr_enable( pdo_rtr_required() );
	}
      else
	return FALSE;
      break;

    case OD_PDO_EVENT_TIMER:
      if( nbytes == 2 || nbytes == 0 )
	{
	  //UINT16 val;
	  //val  = (UINT16) par[0];
	  //val |= ((UINT16) par[1] << 8);
	  //val  = (val / (UINT16) 1000) & (UINT16) 0xFF;
	  /* In units of seconds, but must be <=255 ! */
	  //PdoCommPar[pdo_no].event_timer = (BYTE) val;

	  /* Timer now in units of seconds, <= 65535 */
	  PdoCommPar[pdo_no].event_timer  = (UINT16) par[0];
	  PdoCommPar[pdo_no].event_timer |= (((UINT16) par[1]) << 8);

#ifdef __VARS_IN_EEPROM__
	  if( eeprom_read( EE_PDO_ETIMER_LO+pdo_no ) != par[0] )
	    eeprom_write( EE_PDO_ETIMER_LO+pdo_no, par[0] );
	  if( eeprom_read( EE_PDO_ETIMER_HI+pdo_no ) != par[1] )
	    eeprom_write( EE_PDO_ETIMER_HI+pdo_no, par[1] );
#endif /* __VARS_IN_EEPROM__ */
	}
      else
	return FALSE;
      break;

    default:
      /* The sub-index does not exist */
      return FALSE;
    }

#ifdef __VARS_IN_EEPROM__
  PdoCommPar[pdo_no].transmission_type = eeprom_read(EE_PDO_TTYPE+pdo_no);
  PdoCommPar[pdo_no].event_timer       =
    ((UINT16) eeprom_read( EE_PDO_ETIMER_LO + pdo_no )) |
    (((UINT16) eeprom_read( EE_PDO_ETIMER_HI + pdo_no )) << 8);
#endif /* __VARS_IN_EEPROM__ */

  /* Update the PDO Event Timer stuff if necessary */
  TPdoOnTimer[pdo_no] = ((PdoCommPar[pdo_no].transmission_type >= 254)
			 && (PdoCommPar[pdo_no].event_timer > (UINT16)0));
#ifdef __VARS_IN_EEPROM__
  if( eeprom_read( EE_TPDO_ONTIMER+pdo_no ) != TPdoOnTimer[pdo_no] )
    eeprom_write( EE_TPDO_ONTIMER+pdo_no, TPdoOnTimer[pdo_no] );
#endif /* __VARS_IN_EEPROM__ */

  /* Immediately start first timer-triggered read out, if enabled... */
  TIMER1_DISABLE();
  TPdoTimerCntr[pdo_no] = PdoCommPar[pdo_no].event_timer;
  TIMER1_ENABLE();
  
  return TRUE;
}

/* ------------------------------------------------------------------------ */

static BOOL pdo_get_comm_par( BYTE pdo_no,
			      BYTE od_subind,
			      BYTE *nbytes,
			      BYTE *par )
{
  switch( od_subind )
    {
    case OD_NO_OF_ENTRIES:
      par[0]  = 5;
      *nbytes = 1;
      break;

    case OD_PDO_COBID:
      {
	UINT16 cob_id;
#ifdef __VARS_IN_EEPROM__
	NodeID = eeprom_read( EE_NODEID );
#endif /* __VARS_IN_EEPROM__ */

	/* Default values... */
	cob_id = PDO_COBID[pdo_no] | NodeID;

	par[0] = (BYTE) ((cob_id & (UINT16) 0x00ff) >> 0);
	par[1] = (BYTE) ((cob_id & (UINT16) 0xff00) >> 8);
	par[2] = 0x00;
	par[3] = 0x00;
	*nbytes = 4;
      }
      break;

    case OD_PDO_TRANSMTYPE:
#ifdef __VARS_IN_EEPROM__
      PdoCommPar[pdo_no].transmission_type = eeprom_read(EE_PDO_TTYPE+pdo_no);
#endif /* __VARS_IN_EEPROM__ */

      par[0]  = PdoCommPar[pdo_no].transmission_type;
      *nbytes = 1;
      break;

    case OD_PDO_INHIBITTIME:
      par[0]  = 0x00;
      par[1]  = 0x00;
      *nbytes = 2;
      break;

    case OD_PDO_DUMMY_ENTRY:
      par[0]  = 0x00;
      *nbytes = 1;
      break;

    case OD_PDO_EVENT_TIMER:
      {
	//UINT16 val;
#ifdef __VARS_IN_EEPROM__
	PdoCommPar[pdo_no].event_timer       =
	  ((UINT16) eeprom_read( EE_PDO_ETIMER_LO + pdo_no )) |
	  (((UINT16) eeprom_read( EE_PDO_ETIMER_HI + pdo_no )) << 8);
#endif /* __VARS_IN_EEPROM__ */

	/* In units of seconds, but must be <=255 ! */
	//val = (UINT16) 1000 * PdoCommPar[pdo_no].event_timer;
	//par[0] = (BYTE) ((val & (UINT16) 0x00FF) >> 0);
	//par[1] = (BYTE) ((val & (UINT16) 0xFF00) >> 8);

	/* Timer now in units of seconds, <= 65535 */
	par[0] = (BYTE) (PdoCommPar[pdo_no].event_timer & (UINT16) 0x00FF);
	par[1] = (BYTE) ((PdoCommPar[pdo_no].event_timer &
			  (UINT16) 0xFF00) >> 8);
	*nbytes = 2;
      }
      break;

    default:
      /* The sub-index does not exist */
      return FALSE;
    }

  return TRUE;
}

/* ------------------------------------------------------------------------ */

static BOOL pdo_get_mapping( BYTE pdo_no,
			     BYTE od_subind,
			     BYTE *nbytes,
			     BYTE *par )
{
  if( od_subind == OD_NO_OF_ENTRIES )
    {
      par[0] = PDOMAP_CNT[pdo_no];
      *nbytes = 1;
    }
  else
    {
      if( od_subind <= PDOMAP_CNT[pdo_no] )
	{
	  BYTE i;
	  const BYTE *p = (const BYTE *) &PDOMAP[pdo_no][od_subind-1];

	  for( i=0; i<4; ++i, ++p ) par[i] = *p;

	  *nbytes = 4;
	}
      else
	{
	  /* The sub-index does not exist */
	  return FALSE;
	}
    }
  return TRUE;
}

/* ------------------------------------------------------------------------ */

/* Note that not all PDO parameters fit in one storage block (16 bytes max)
   when there are more than 5 PDOs */
#define PDO_STORE_SIZE ((TPDO_CNT + RPDO_CNT) * sizeof(PDO_COMM_PAR))
// Split in 2 parts if necessary:
//#define TPDO_STORE_SIZE (TPDO_CNT * sizeof(PDO_COMM_PAR))
//#define RPDO_STORE_SIZE (RPDO_CNT * sizeof(PDO_COMM_PAR))

/* ------------------------------------------------------------------------ */

BOOL pdo_store_config( void )
{
  BYTE *p;

#ifdef __VARS_IN_EEPROM__
  BYTE i;
  for( i=0; i<TPDO_CNT+RPDO_CNT; ++i )
    {
      PdoCommPar[i].transmission_type = eeprom_read( EE_PDO_TTYPE+i );
      /* Timer now in units of seconds, <= 65535 */
      PdoCommPar[i].event_timer       =
	((UINT16) eeprom_read( EE_PDO_ETIMER_LO + i )) |
	(((UINT16) eeprom_read( EE_PDO_ETIMER_HI + i )) << 8);
    }
#endif /* __VARS_IN_EEPROM__ */

  p = (BYTE *) PdoCommPar;

  /* Store the configuration in EEPROM */
  return( store_write_block( STORE_PDO, PDO_STORE_SIZE, p ) );
}

/* ------------------------------------------------------------------------ */

static void pdo_load_config( void )
{
  BYTE *p;

  p = (BYTE *) PdoCommPar;

  /* Read the configuration from EEPROM, if any */
  if( !store_read_block( STORE_PDO, PDO_STORE_SIZE, p ) )
    {
      /* No valid parameters in EEPROM: use defaults */
      BYTE i;

      /* Set default Transmit-PDO communication parameters */
      for( i=0; i<TPDO_CNT; ++i )
	{
	  PdoCommPar[i].transmission_type = 1;	/* Respond to SYNC */
	  PdoCommPar[i].event_timer       = 0;	/* Seconds between triggers;
						   0 = not timer-triggered */
	}

      /* Set default Receive-PDO communication parameters */
      for( i=TPDO_CNT; i<RPDO_CNT+TPDO_CNT; ++i )
	{
	  PdoCommPar[i].transmission_type = 255;/* Profile specific */
	  PdoCommPar[i].event_timer       = 0;	/* not used for tPDOs... */
	}
    }
}

/* ------------------------------------------------------------------------ */

⌨️ 快捷键说明

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