Пример #1
0
void nespad_poll_gamepad(nespad_t* gamepad)
{
	uint8_t local_buff = 0x00;
	// Toggle Latch - which presents the first bit
	bit_set(*gamepad->port, BIT(gamepad->latch_pin));
	_delay_us(PULSE_TIME);
	bit_clr(*gamepad->port, BIT(gamepad->latch_pin));
	_delay_us(PULSE_TIME);

	// Read first bit
	local_buff = bit_get(PIND,BIT(gamepad->data_pin));

	// Now get the next 7 bits with the clock
	  for (int i = 0 ; i < 7 ; ++i)
	  {
		bit_set(*gamepad->port, BIT(gamepad->clock_pin));
		_delay_us(PULSE_TIME);
		bit_clr(*gamepad->port, BIT(gamepad->clock_pin));
	    _delay_us(PULSE_TIME);
	    local_buff = (local_buff << 1) | bit_get(PIND,BIT(gamepad->data_pin));
	  }

	  gamepad->buffer = local_buff;

	  return;
}
Пример #2
0
void set_wind_dir_none (void) {
#ifdef DEBUG
	uart_puts ("nodir\r\n");	
#endif
	bit_clr (PORTD, WIND_CLOCK );
	bit_clr (PORTD, WIND_ANTICLOCK );
    direction=NONE;
}
Пример #3
0
void test_relais(void) {

	
	bit_clr(PORTD, P_BIT4);
	bit_clr(PORTD, P_BIT5);
	bit_clr(PORTD, P_BIT6);
	bit_clr(PORTD, P_BIT7);
	bit_set(PORTD, WIND_CLOCK);
	uart_puts ("0x80\r\n");
	lcd_puts (0, "bit7 (wind-clock)\n");
	delay(2000);

	bit_set(PORTD, MOTOR);
	uart_puts ("0x40\r\n");
	lcd_puts (0, "bit5 (motor)\n");
	delay(2000);

	bit_set(PORTD, FILL_WIND);	
	uart_puts ("0x20\r\n");
	lcd_puts (0, "bit6 (fill-wind)\n");
	delay(2000);

	bit_set(PORTD, WIND_ANTICLOCK);
	uart_puts ("0x10\r\n");
	lcd_puts (0, "bit4 (wind anticlock)\n");
	delay(2000);


	lcd_clrscr(0);
	uart_puts ("mot\r\n");
	lcd_puts (0, "motor\n");

    start_motor();
	delay(2000);
    stop_motor();
	delay(500);

	uart_puts ("fill\r\n");
	lcd_puts (0, "fill\n");
	fill();
	delay(2000);
	stop_motor();

	uart_puts ("windleft\r\n");
	lcd_puts (0, "windleft\n");
    delay(500);
	set_wind_dir_left();
	delay(5000);
	stop_motor();
}
Пример #4
0
void init_mcp3201(uint8_t chip, uint8_t cs, uint8_t clk,  uint8_t data)

{
 uint8_t bclk, bcs, bdout, bdin;
 
 bclk =  1<< (clk & P_BITMASK);
 b_clk[chip]=bclk;
 bdata= 1<< (data & P_BITMASK);
 b_data[chip]=bdout;
 bcs= 1<< (cs   & P_BITMASK);
 b_cs[chip] = bcs;

 clk=clk & P_PORTMASK;
 if (clk==P_PORTA) {p_clk[chip]=&PORTA; DDRA|=bclk;  }
 if (clk==P_PORTB) {p_clk[chip]=&PORTB; DDRB|=bclk;}
 if (clk==P_PORTC) {p_clk[chip]=&PORTC; DDRC|=bclk;}
 if (clk==P_PORTD) {p_clk[chip]=&PORTD; DDRD|=bclk;}

 data=data & P_PORTMASK;              
 if (data==P_PORTA) {p_data[chip]=&PINA; DDRA&=~bdout; bit_set(PORTA, bdata);}
 if (data==P_PORTB) {p_data[chip]=&PINB; DDRB&=~bdout; bit_set(PORTB, bdata);}
 if (data==P_PORTC) {p_data[chip]=&PINC; DDRC&=~bdout; bit_set(PORTC, bdata);}
 if (data==P_PORTD) {p_data[chip]=&PIND; DDRD&=~bdout; bit_set(PORTD, bdata);}

 cs=cs & P_PORTMASK;
 if (cs==P_PORTA) {p_cs[chip]=&PORTA; DDRA|=bcs;}
 if (cs==P_PORTB) {p_cs[chip]=&PORTB; DDRB|=bcs;}
 if (cs==P_PORTC) {p_cs[chip]=&PORTC; DDRC|=bcs;}
 if (cs==P_PORTD) {p_cs[chip]=&PORTD; DDRD|=bcs;}

 bit_set(*p_cs[chip], b_cs[chip]);
 bit_clr(*p_clk[chip], b_clk[chip]);
 bit_set(*p_din[chip], b_din[chip]);  
}
Пример #5
0
void SWPwm::run() {
	SWPWM_T *ch;
	LIST_POS pos;
	while(1) {
		// wait timer interrupt
		m_timer.wait();

		pos = m_lstCH.getHeadPos();							// get first channel
		while(pos) {
			ch = (SWPWM_T *)m_lstCH.getAt(pos);				// get channel from list
			if ( ch ) {
				ch->flag++;									// inc pwm count
				if (  ch->dutyCycle>0 ) {
					if ( bit_chk(ch->flag, CH_STATE) ) {
						if ( CH_COUNT>=ch->dutyCycle ) {		// count to dutyCycle?
							ch->pin = LOW;						// set output low
							bit_clr(ch->flag, CH_STATE);		// change state
						}
					} else if ( CH_COUNT>=m_accuracy ) {		// count to end ?
						ch->pin = HIGH;							// set output high
						ch->flag = bit(CH_STATE);				// change state & RESET count
					}
				} else {
					ch->pin = LOW;								// always LOW when dutycycle=0
				}
			}
			pos = m_lstCH.getNext(pos);						// next channel
		}
		m_cycle++;
	}
}
Пример #6
0
void set_wind_dir_left (void) {
#ifdef DEBUG
	uart_puts ("left\r\n");	
#endif
	bit_clr (PORTD, WIND_CLOCK );
	bit_set (PORTD, WIND_ANTICLOCK );	
    direction=LEFT;
}
Пример #7
0
void set_wind_dir_right (void) {
#ifdef DEBUG
	uart_puts ("right\r\n");
#endif
	bit_set (PORTD, WIND_CLOCK );
	bit_clr (PORTD, WIND_ANTICLOCK );
    direction=RIGHT;
	
}
Пример #8
0
Файл: event.c Проект: WareX97/K2
extern int set_event(control_t* ctrl, int event, unsigned char enabled) {
	if(enabled) {
		bit_set(ctrl->events, event);
	} else {
		bit_clr(ctrl->events, event);
	}
		
	return 0;
}
void hitachi_lcd_service(void){   
   if(NewCustomSymbolFlags){
      set_flag(CGRAMUsed);
      static uint8_t DataByteNumber = 0, CustomSymbolNumber = 0;
      if(get_flag(CGRAMAddrSet)){
         hitachi_lcd_write_data(*(CustomSymbol[CustomSymbolNumber] + DataByteNumber));
         if(++DataByteNumber > 7){
            bit_clr(NewCustomSymbolFlags, CustomSymbolNumber);
            clr_flag(CGRAMAddrSet);
            DataByteNumber = 0;
            CustomSymbolNumber = 0;
         }
      } else {
         while(!(NewCustomSymbolFlags & (1<<CustomSymbolNumber)))
            CustomSymbolNumber++;
         hitachi_lcd_set_address(CGRAM_ADDR(CustomSymbolNumber*8));
         set_flag(CGRAMAddrSet);
      }
   } else {
      if(get_flag(CGRAMUsed)){
         clr_flag(CGRAMUsed);
         clr_flag(DRAMAddrSet);
         CharNumber = 0;
         hitachi_lcd_set_address(DRAM_ADDR(0x00));
      } else {
         switch(CharNumber){
           case CHAR_IN_ROW:
            if(get_flag(DRAMAddrSet)){
               clr_flag(DRAMAddrSet);
               hitachi_lcd_write_data(pLcdBuffer[CharNumber]);
               CharNumber++;
            } else {
               set_flag(DRAMAddrSet);
               hitachi_lcd_set_address(DRAM_ADDR(0x40));
            }
            break;
            
           case CHAR_ON_LCD:
            if(get_flag(DRAMAddrSet)){
               clr_flag(DRAMAddrSet);
               CharNumber = 0;
               hitachi_lcd_write_data(pLcdBuffer[CharNumber]);
               CharNumber++;
            } else {
               set_flag(DRAMAddrSet);
               hitachi_lcd_set_address(DRAM_ADDR(0x00));
            }
            break;
            
           default:
            hitachi_lcd_write_data(pLcdBuffer[CharNumber]);
            CharNumber++;
            break;
         }
      }
   }
}
Пример #10
0
bool CAdcKey::isPressed(ADKEY_T key, bool clearFlag) {
	bool res = bit_chk(m_flag, key);
	if (res && clearFlag) {
		m_mutex.lock();
		bit_clr(m_flag, key);
		m_mutex.unlock();
	}
	return res;
}
Пример #11
0
void fill (void) {
#ifdef DEBUG
	uart_puts ("fill\r\n");
#endif
	set_wind_dir_none ();
	bit_clr (PORTD, FILL_WIND );
	turns_done=0;
	action=FILL;
	delay(100);
	start_motor();
}
Пример #12
0
void mcp4922_spiw (uint8_t chip, int16_t word, uint8_t dac)


{
 volatile uint8_t *pcs, *pldac;
 uint8_t bcs, bldac;

 if ((word & CNTRL)==0) {
     word|=DEFAULT;
     if (dac==0) word|=DAC_A;
     }

 pcs=p_cs[chip];
 pldac=p_ldac[chip];

 bcs=b_cs[chip];
 bldac=b_ldac[chip];

 uart_printf ("pcs1:%x\n",pcs);
// pcs=&PORTA;
 bit_clr(*pcs, bcs);
// uart_printf ("pcs2:%d\n",pcs);
 
 
 
 SPDR= word>>8;
 while (!(SPSR & (1<<SPIF)));
 SPDR= word & 0xff;
 while (!(SPSR & (1<<SPIF)));



        
// PORTA|=bcs;
 bit_set(*pcs, bcs);
 bit_clr(*pldac, bldac);
 udelay(2);
 bit_set(*pldac, bldac);


}
Пример #13
0
unsigned int mcp3201_getw (uint8_t chip)


{
 volatile uint8_t *pclk, *pcs, *pdata;
 uint8_t bclk, bcs, bdata;
 uint8_t v,i;
 unsigned int word;

 pclk=p_clk[chip];
 pdata=p_data[chip];
 pcs=p_cs[chip];

 bclk=b_clk[chip];
 bdata=b_data[chip];
 bcs=b_cs[chip];

 bit_clr(*pclk, bclk);
 bit_clr(*pcs, bcs);

 udelay (20);
 word=0;
 for (i=0; i<16; i++) {

     bit_set(*pclk, bclk);
     udelay(100);
     bit_clr(*pclk, bclk);
     udelay(100);          
     word=word<<1;
     if (bit_get (*pdout, bdout)) word++;    
     }

 udelay (100);
 bit_set(*pcs, bcs);

 return ((word>>1) & 0x0fff);
}
Пример #14
0
void potentiometer()
{ int sinus [21] = {128,168,203,232,250,255,250,232,203,168,128,88,53,24,6,0,6,24,53,88,128};
  while(1)
   {  for(int i=0;i<20;i++)         // send data to SPDR
            { bit_clr (PORTB,PB5);           // set CS low
              SPDR =  0b00010001;           // command byte     
              while ((SPSR & 0x80) == 0)
              {}
              SPDR = sinus[i];
              while ((SPSR & 0x80) == 0)
              {}
              bit_set(PORTB,PB5);           // set CS high PINB = 0b00010000;
              _delay_ms(5);
            }
    }
}
Пример #15
0
void init_mcp4922(uint8_t chip, uint8_t cs, uint8_t clk,  uint8_t data, uint8_t ldac )

{
 uint8_t bclk, bcs, bdata, bldac;

 
 bclk=1<< (clk  & P_BITMASK);
 b_clk [chip] = bclk;
 bdata=1<< (data & P_BITMASK); 
 b_data[chip] = bdata;
 bcs=1<< (cs   & P_BITMASK); 
 b_cs  [chip] =  bcs;
 
 bldac=1<< (ldac & P_BITMASK); 
 b_ldac[chip] = bldac;
 

 clk=clk & P_PORTMASK;
 if (clk==P_PORTA) {p_clk[chip]=&PORTA; DDRA|=bclk ;}
 if (clk==P_PORTB) {p_clk[chip]=&PORTB; DDRB|=bclk;}
 if (clk==P_PORTC) {p_clk[chip]=&PORTC; DDRC|=bclk;}
 if (clk==P_PORTD) {p_clk[chip]=&PORTD; DDRD|=bclk;}

 data=data & P_PORTMASK;
 if (data==P_PORTA) {p_data[chip]=&PORTA; DDRA|=bdata;}
 if (data==P_PORTB) {p_data[chip]=&PORTB; DDRB|=bdata;}
 if (data==P_PORTC) {p_data[chip]=&PORTC; DDRC|=bdata;}
 if (data==P_PORTD) {p_data[chip]=&PORTD; DDRD|=bdata;}


 cs=cs & P_PORTMASK;
 if (cs==P_PORTA) {p_cs[chip]=&PORTA; DDRA|=bcs;}
 if (cs==P_PORTB) {p_cs[chip]=&PORTB; DDRB|=bcs;}
 if (cs==P_PORTC) {p_cs[chip]=&PORTC; DDRC|=bcs;}
 if (cs==P_PORTD) {p_cs[chip]=&PORTD; DDRD|=bcs;}


 ldac=ldac & P_PORTMASK;
 if (ldac==P_PORTA) {p_ldac[chip]=&PORTA; DDRA|=bldac;}
 if (ldac==P_PORTB) {p_ldac[chip]=&PORTB; DDRB|=bldac;}
 if (ldac==P_PORTC) {p_ldac[chip]=&PORTC; DDRC|=bldac;}
 if (ldac==P_PORTD) {p_ldac[chip]=&PORTD; DDRD|=bldac;}
 
 bit_set(*p_cs[chip], b_cs[chip]);
 bit_clr(*p_clk[chip], b_clk[chip]);
 bit_set(*p_ldac[chip], b_ldac[chip]); 
}
Пример #16
0
void i2c_stop()
{
	// STOP
	TWCR = _BV(TWINT)|_BV(TWEN)|_BV(TWSTO);

	// Wait for STOP
	// WARNING: A bad I2C line can cause this loop to hang
	//loop_until_bit_is_set(TWCR, TWSTO);
	byte counter = 255; // 255 * 5us = 1.275ms timeout
	while(bit_is_clear(TWCR, TWSTO) && counter--)
		delay_us(5);

	// Disable I2C
	bit_clr(TWCR, TWEN);

	power_twi_disable();
}
Пример #17
0
void setup()
{
	// Init USI TWI Slave and enable interrupts
	usiTwiSlaveInit(NESPAD_SLAVE_ADDRESS, i2cReadFromRegister, i2cWriteToRegister);
	sei();

	// clock / latch pair for gamepad 1
	bit_set(DDRD, BIT(NES_CLOCK_1));
	bit_set(DDRD, BIT(NES_LATCH_1));

	// clock / latch pair for gamepad 2
	bit_set(DDRB, BIT(NES_CLOCK_2));
	bit_set(DDRB, BIT(NES_LATCH_2));

	// shared data pin for all gamepads
	bit_clr(DDRD, BIT(NES_DATA));
}
Пример #18
0
int main( int argc, char **argv )
{
   unsigned long t = 0;

   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );

   bit_set( &t, 0 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 1 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 2 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 3 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 4 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 5 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 6 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 7 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 31 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 30 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 29 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 28 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_set( &t, 27 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );

   printf( "\n" );
   bit_clr( &t, 0 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_clr( &t, 31 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_clr( &t, 1 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_clr( &t, 4 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   bit_clr( &t, 7 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );
   
   printf( "\n" );
   bit_clr( &t, 16 );
   printf( "0x%08lx has %d bits set\n", t, bit_cnt( &t ) );

   return 0;
}
Пример #19
0
bool i2c_read(byte* data, bool ack)
{
	// Expects more data (ACK) or not (NACK)
	ack ? (bit_set(TWCR, TWEA)) : (bit_clr(TWCR, TWEA));

	// Begin receiving
	bit_set(TWCR, TWINT);

	// Wait for finish
	loop_until_bit_is_set(TWCR, TWINT);

	// Check status
	byte status = TW_STATUS;
	if(status != TW_MR_DATA_ACK && status != TW_MR_DATA_NACK)
		return false;

	// Read data
	*data = TWDR;
	return true;
}
Пример #20
0
// Reset to known state (as per what the DS3231 datasheet says)
void i2c_resetState()
{
	bit_clr(TWCR, TWEN); // Disable TWI
	pinMode(SDA, INPUT);
	pinPullup(SDA, PULLUP_ENABLE);
	delay(1);

	// Toggle SDL until SDA goes HIGH or times out
	byte count = 64; // 64 * 1ms = 64ms timeout
	while(!pinRead(SDA) && count--)
	{
		delay(1);
		pinWrite(SDL, TOGGLE);
	}

	// Back to normal
	pinMode(SDA, OUTPUT);
	pinMode(SDL, OUTPUT);
	pinWrite(SDA, HIGH);
	pinWrite(SDL, HIGH);
}
Пример #21
0
uint8_t ADT_check()
{
	uint8_t i;
	for(i=0;i<ADT_sensor_count;i++)
	{
		#ifdef debug
		uart_print("ADT chk: ");
		uart_num(i,1);
		#endif	
		if(i2c_start(ADT_addr_base|i,I2C_READ))
		{
			bit_set(ADT_status,BIT(i));//set Ith bit as sign of sensor error
			#ifdef debug
				uart_println(" FAIL");
			#endif
		}
		else
		{
			i2c_read(0);
			bit_clr(ADT_status,BIT(i));//set as working
			#ifdef debug
			uart_println(" OK");
			#endif
		}
		i2c_stop();
		
	}

	if(ADT_minimum_working > ADT_get_working_count())
	{
		error_flags.ADT=1;
		return 1;
	}
	else
	{	
		error_flags.ADT=0;
		return 0;
	}
}
Пример #22
0
void mcp4922_putw (uint8_t chip, int16_t word, uint8_t dac)


{
 volatile uint8_t *pclk, *pcs, *pdata, *pldac;
 uint8_t bclk, bcs, bdata, bldac;
 uint8_t i;


 if ((word & CNTRL)==0) {
     word|=DEFAULT;
     if (dac==0) word|=DAC_A;
     }

 pclk=p_clk[chip];
 pdata=p_data[chip];
 pcs=p_cs[chip];
 pldac=p_ldac[chip];

 bclk=b_clk[chip];
 bdata=b_data[chip];
 bcs=b_cs[chip];
 bldac=b_ldac[chip];

 bit_clr(*pcs, bcs);
 bit_clr (*pdata, bdata);

  
 for (i=0; i<16; i++) {

     bit_clr(*pclk, bclk);
     if ((word & 0x8000)) {
          bit_set (*pdata, bdata);
          }
     else {
           bit_clr (*pdata, bdata);
           }     
     bit_set(*pclk, bclk);                    
     word=word<<1;     
     }
 bit_clr(*pclk, bclk);
 bit_set(*pcs, bcs);
 bit_clr(*pldac, bldac); 
 udelay(2);
 bit_set(*pldac, bldac);
}
Пример #23
0
void CButton::run() {
	CTimeout bounce;
	while(1) {
		if ( bit_chk(m_flag, KEY_FLAG_DOWN) ) {
			if ( m_pin==HIGH ){
				if ( bounce.isExpired(10)  ) {
					bit_clr(m_flag, KEY_FLAG_DOWN);
					onKeyUp();		// call virtual function "onKeyUp()"
				}
			} else {
				bounce.reset();
			}
		} else {
			if ( m_pin==LOW ){
				if ( bounce.isExpired(5)  ) {
					bit_set(m_flag, KEY_FLAG_DOWN);
					onKeyDown();	// call virtual function "onKeyDown()"
				}
			} else {
				bounce.reset();
			}
		}
	}
}
Пример #24
0
void tab_parse(char *file, char *user)
/* Parse a crontab file and add its data to the tables.  Handle errors by
 * yourself.  Table is owned by 'user' if non-null.
 */
{
	crontab_t **atab, *tab;
	cronjob_t **ajob, *job;
	int fd;
	struct stat st;
	char *p, *q;
	size_t n;
	ssize_t r;
	int ok, wc;

	for (atab= &crontabs; (tab= *atab) != nil; atab= &tab->next) {
		if (strcmp(file, tab->file) == 0) break;
	}

	/* Try to open the file. */
	if ((fd= open(file, O_RDONLY)) < 0 || fstat(fd, &st) < 0) {
		if (errno != ENOENT) {
			log(LOG_ERR, "%s: %s\n", file, strerror(errno));
		}
		if (fd != -1) close(fd);
		return;
	}

	/* Forget it if the file is awfully big. */
	if (st.st_size > TAB_MAX) {
		log(LOG_ERR, "%s: %lu bytes is bigger than my %lu limit\n",
			file,
			(unsigned long) st.st_size,
			(unsigned long) TAB_MAX);
		return;
	}

	/* If the file is the same as before then don't bother. */
	if (tab != nil && st.st_mtime == tab->mtime) {
		close(fd);
		tab->current= 1;
		return;
	}

	/* Create a new table structure. */
	tab= allocate(sizeof(*tab));
	tab->file= allocate((strlen(file) + 1) * sizeof(tab->file[0]));
	strcpy(tab->file, file);
	tab->user= nil;
	if (user != nil) {
		tab->user= allocate((strlen(user) + 1) * sizeof(tab->user[0]));
		strcpy(tab->user, user);
	}
	tab->data= allocate((st.st_size + 1) * sizeof(tab->data[0]));
	tab->jobs= nil;
	tab->mtime= st.st_mtime;
	tab->current= 0;
	tab->next= *atab;
	*atab= tab;

	/* Pull a new table in core. */
	n= 0;
	while (n < st.st_size) {
		if ((r = read(fd, tab->data + n, st.st_size - n)) < 0) {
			log(LOG_CRIT, "%s: %s", file, strerror(errno));
			close(fd);
			return;
		}
		if (r == 0) break;
		n+= r;
	}
	close(fd);
	tab->data[n]= 0;
	if (strlen(tab->data) < n) {
		log(LOG_ERR, "%s contains a null character\n", file);
		return;
	}

	/* Parse the file. */
	ajob= &tab->jobs;
	p= tab->data;
	ok= 1;
	while (ok && *p != 0) {
		q= get_token(&p);
		if (*q == '#' || q == p) {
			/* Comment or empty. */
			while (*p != 0 && *p++ != '\n') {}
			continue;
		}

		/* One new job coming up. */
		*ajob= job= allocate(sizeof(*job));
		*(ajob= &job->next)= nil;
		job->tab= tab;

		if (!range_parse(file, q, job->min, 0, 59, &wc)) {
			ok= 0;
			break;
		}

		q= get_token(&p);
		if (!range_parse(file, q, job->hour, 0, 23, &wc)) {
			ok= 0;
			break;
		}

		q= get_token(&p);
		if (!range_parse(file, q, job->mday, 1, 31, &wc)) {
			ok= 0;
			break;
		}
		job->do_mday= !wc;

		q= get_token(&p);
		if (!range_parse(file, q, job->mon, 1, 12, &wc)) {
			ok= 0;
			break;
		}
		job->do_mday |= !wc;

		q= get_token(&p);
		if (!range_parse(file, q, job->wday, 0, 7, &wc)) {
			ok= 0;
			break;
		}
		job->do_wday= !wc;

		/* 7 is Sunday, but 0 is a common mistake because it is in the
		 * tm_wday range.  We allow and even prefer it internally.
		 */
		if (bit_isset(job->wday, 7)) {
			bit_clr(job->wday, 7);
			bit_set(job->wday, 0);
		}

		/* The month range is 1-12, but tm_mon likes 0-11. */
		job->mon[0] >>= 1;
		if (bit_isset(job->mon, 8)) bit_set(job->mon, 7);
		job->mon[1] >>= 1;

		/* Scan for options. */
		job->user= nil;
		while (q= get_token(&p), *q == '-') {
			q++;
			if (q[0] == '-' && q+1 == p) {
				/* -- */
				q= get_token(&p);
				break;
			}
			while (q < p) switch (*q++) {
			case 'u':
				if (q == p) q= get_token(&p);
				if (q == p) goto usage;
				memmove(q-1, q, p-q);	/* gross... */
				p[-1]= 0;
				job->user= q-1;
				q= p;
				break;
			default:
			usage:
				log(LOG_ERR,
			"%s: bad option -%c, good options are: -u username\n",
					file, q[-1]);
				ok= 0;
				goto endtab;
			}
		}

		/* A crontab owned by a user can only do things as that user. */
		if (tab->user != nil) job->user= tab->user;

		/* Inspect the first character of the command. */
		job->cmd= q;
		if (q == p || *q == '#') {
			/* Rest of the line is empty, i.e. the commands are on
			 * the following lines indented by one tab.
			 */
			while (*p != 0 && *p++ != '\n') {}
			if (*p++ != '\t') {
				log(LOG_ERR, "%s: contains an empty command\n",
					file);
				ok= 0;
				goto endtab;
			}
			while (*p != 0) {
				if ((*q = *p++) == '\n') {
					if (*p != '\t') break;
					p++;
				}
				q++;
			}
		} else {
			/* The command is on this line.  Alas we must now be
			 * backwards compatible and change %'s to newlines.
			 */
			p= q;
			while (*p != 0) {
				if ((*q = *p++) == '\n') break;
				if (*q == '%') *q= '\n';
				q++;
			}
		}
		*q= 0;
		job->rtime= now;
		job->late= 0;		/* It is on time. */
		job->atjob= 0;		/* True cron job. */
		job->pid= IDLE_PID;	/* Not running yet. */
		tab_reschedule(job);	/* Compute next time to run. */
	}
  endtab:

	if (ok) tab->current= 1;
}
Пример #25
0
// 数据包超时心跳包, 定时器自动复位, 一个单位时间一次
void heart_beart_notify_proc(Hachiko_EVT evt, void* _private, const struct Hachiko_food *self)
{
    static int food = 0;

    if (evt == HACHIKO_TIMEOUT ) {
        unsigned int i = 0;
        struct charge_job * thiz = (struct charge_job *)_private;
        struct can_pack_generator *gen, *me;

        food ++;
        if ( food == 1000 ) {
            // 1S 为更新周期
            thiz->bms.frame_speed_tx = thiz->bms.tx_seed;
            thiz->bms.frame_speed_rx = thiz->bms.rx_seed;
            thiz->bms.tx_seed = 0;
            thiz->bms.rx_seed = 0;
           food = 0;
        }

        for ( i = 0; thiz && i < thiz->bms.can_pack_gen_nr; i++ ) {
            gen = & thiz->bms.generator[i];
            if ( gen->stage == thiz->bms.charge_stage ) {
                if ( gen->heartbeat < gen->period ) {
                    gen->heartbeat += 1;
                } else {
                    gen->heartbeat = gen->period;
                }
            } else {
                gen->heartbeat = 0;
            }
        }


        /*
         * 为了能够侦探到接受数据包的超时事件,需要在这里进行一个计数操作
         * 当can_silence 计数大于等于 can_tolerate_silence 时认为对应数据包接收超时,需要在BMS逻辑主线程
         * 中做相应处理.
         *
         * BEM和CEM不在超时统计范围内
         */
        for ( i = 0; thiz && i < thiz->bms.can_pack_gen_nr; i++ ) {
            me = &thiz->bms.generator[i];
            //if ( bit_read(thiz, JF_GUN_OK) && bit_read(thiz, JF_ASSIT_PWR_ON) ) {
                if ( me->stage == thiz->bms.charge_stage ) {
                    me->can_silence ++;
                } else {
                    me->can_silence = 0;
                }
            //} else continue;
            if ( me->can_tolerate_silence < me->can_silence ) {
                switch (thiz->bms.charge_stage) {
                case CHARGE_STAGE_HANDSHACKING:
                    if (me->can_pgn != PGN_BRM) break;
                        if ( !bit_read(thiz, JS_BMS_RX_BRM_TIMEOUT) &&
                             !bit_read(thiz, JF_CHG_TRM_CHARGE) &&
                             !bit_read(thiz, JF_BMS_TRM_CHARGE) ) {
                            bit_set(thiz, JS_BMS_RX_BRM_TIMEOUT);
                            bit_clr(thiz, JF_BMS_BRM_OK);
                            log_printf(WRN, "BMS: 握手阶段BMS通信"RED("故障(%d, V(RX):%d, V(TX):%d)")", 重新握手",
                                       me->can_tolerate_silence,
                                       thiz->bms.frame_speed_rx,
                                       thiz->bms.frame_speed_tx);
                            thiz->bms.charge_stage = CHARGE_STAGE_HANDSHACKING;
                            // 设置BMS通讯超时标志
                            // bit_set(thiz, JS_BMS_COMM_ERR);
                        } else {
                            me->can_silence = 0;
                        }
                    break;
                case CHARGE_STAGE_CONFIGURE:
                    if (me->can_pgn != PGN_BRO && me->can_pgn != PGN_BCP ) break;
                        if ( me->can_pgn == PGN_BRO && !bit_read(thiz, JS_BMS_RX_BRO_TIMEOUT) ) {
                            bit_set(thiz, JS_BMS_RX_BRO_TIMEOUT);
                            bit_clr(thiz, JF_BMS_RX_BRO);
                        } else {
                            me->can_silence = 0;
                        }

                        if ( me->can_pgn == PGN_BCP && !bit_read(thiz, JS_BMS_RX_BCP_TIMEOUT) ) {
                            bit_set(thiz, JS_BMS_RX_BCP_TIMEOUT);
                            bit_clr(thiz, JF_BMS_RX_BCP);
                        } else {
                            me->can_silence = 0;
                        }

                        if ( bit_read(thiz, JS_BMS_RX_BRO_TIMEOUT ) &&
                             bit_read(thiz, JS_BMS_RX_BCP_TIMEOUT ) &&
                             !bit_read(thiz, JF_CHG_TRM_CHARGE) &&
                             !bit_read(thiz, JF_BMS_TRM_CHARGE) ) {
                            log_printf(WRN, "BMS: 配置阶段BMS通信"RED("故障(%d, V(RX):%d, V(TX):%d)")", 重新握手",
                                       me->can_tolerate_silence,
                                       thiz->bms.frame_speed_rx,
                                       thiz->bms.frame_speed_tx);
                            thiz->bms.charge_stage = CHARGE_STAGE_HANDSHACKING;
                        }
                    break;
                case CHARGE_STAGE_CHARGING:
                    if ( me->can_pgn == PGN_BCL ) {
                        if ( !bit_read(thiz, JS_BMS_RX_BCL_TIMEOUT) &&
                             !bit_read(thiz, JF_CHG_TRM_CHARGE) &&
                             !bit_read(thiz, JF_BMS_TRM_CHARGE) ) {
                            bit_set(thiz, JS_BMS_RX_BCL_TIMEOUT);
                            bit_clr(thiz, JF_BMS_RX_BCL);
                            log_printf(WRN, "BMS: 充电阶段BMS通信"RED("故障(%d, V(RX):%d, V(TX):%d)")", 重新握手",
                                       me->can_tolerate_silence,
                                       thiz->bms.frame_speed_rx,
                                       thiz->bms.frame_speed_tx);
                            thiz->bms.charge_stage = CHARGE_STAGE_HANDSHACKING;
                        } else {
                            me->can_silence = 0;
                        }
                    } else if ( me->can_pgn == PGN_BST &&
                                (bit_read(thiz, JF_CHG_TRM_CHARGE) ||
                                 bit_read(thiz, JF_BMS_TRM_CHARGE)) ) {
                        bit_set(thiz, JS_BMS_RX_BST_TIMEOUT);
                        log_printf(INF, "BMS: 接收BMS.BST 超时");
                        thiz->bms.charge_stage = CHARGE_STAGE_DONE;
                    } else {
                        break;
                    }
                    break;
                case CHARGE_STAGE_DONE:
                    if (me->can_pgn != PGN_BSD) break;
                        if ( !bit_read(thiz, JS_BMS_RX_BSD_TIMEOUT) &&
                             ! bit_read(thiz, JF_BMS_RX_BSD) ) {
                            bit_set(thiz, JS_BMS_RX_BSD_TIMEOUT);
                            log_printf(WRN, "BMS: 充电完成阶段BMS通信"RED("故障(%d, V(RX):%d, V(TX):%d)"),
                                       me->can_tolerate_silence,
                                       thiz->bms.frame_speed_rx,
                                       thiz->bms.frame_speed_tx);
                        } else {
                            me->can_silence = 0;
                        }
                    break;
                default:
                    break;
                }
            }
        }
    }
}
Пример #26
0
void start_motor (void){
#ifdef DEBUG
	uart_puts ("start motor\r\n");
#endif
	bit_clr (PORTD, MOTOR );
}
Пример #27
0
// CAN数据包接受完成
int about_packet_reciev_done(struct charge_job *thiz, struct bms_event_struct *param)
{
    struct can_pack_generator *gen = NULL;

    switch ( param->can_id & 0x00FF00 ) {
    case PGN_CRM :// 0x000100,
        break;
    case PGN_CTS :// 0x000700,
        break;
    case PGN_CML :// 0x000800,
        break;
    case PGN_CCS :// 0x001200,
        break;
    case PGN_CST :// 0x001A00,
        bit_set(thiz, F_PCK_TX_CST);
        log_printf(INF, "BMS: PGN_CST 已经发送.");
        //thiz->bms.charge_stage = CHARGE_STAGE_DONE;
        log_printf(INF,
          "BMS: CHARGER change stage to "RED("CHARGE_STAGE_DONE"));
        break;
    case PGN_CSD :// 0x001D00,
        bit_set(thiz, F_PCK_TX_CSD);
        log_printf(INF, "BMS: PGN_CSD 已经发送.");
        break;
    case PGN_CRO :// 0x000A00,
        break;
    case PGN_CEM :// 0x001F00
        break;
    case PGN_BRM :// 0x000200, BMS 车辆辨识报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BRM);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        if ( bit_read(thiz, S_BMS_COMM_DOWN) ) {
            log_printf(INF, "BMS: BMS 通信"GRN("恢复"));
        }
        bit_clr(thiz, S_BMS_COMM_DOWN);
        //__dump_can_param(param);

        if ( param->buff_payload == 8 ) {
            memcpy(&thiz->bms.vehicle_info, param->buff.rx_buff, 8);
        } else if ( param->buff_payload == sizeof(struct pgn512_BRM) ) {
            memcpy(&thiz->bms.vehicle_info,
                   param->buff.rx_buff, sizeof(struct pgn512_BRM));
        }

        if ( thiz->bms.vehicle_info.spn2565_bms_version[0] == 0x00 &&
             thiz->bms.vehicle_info.spn2565_bms_version[1] == 0x01 &&
             thiz->bms.vehicle_info.spn2565_bms_version[2] == 0x00 ) {

        } else {
            log_printf(WRN,
                  "BMS: BMS not recognized due to invalid BMS VERSION(SPN2565)."
                       "%02X%02X%02X",
                       thiz->bms.vehicle_info.spn2565_bms_version[0],
                       thiz->bms.vehicle_info.spn2565_bms_version[1],
                       thiz->bms.vehicle_info.spn2565_bms_version[2]);
            bit_clr(thiz, F_BMS_RECOGNIZED);
            break;
        }

        if ( thiz->bms.vehicle_info.spn2566_battery_type == 0 ||
             (thiz->bms.vehicle_info.spn2566_battery_type > 0x08 &&
              thiz->bms.vehicle_info.spn2566_battery_type < 0xFF) ) {
            log_printf(WRN,
                   "BMS: BMS not recognized due to invalid BATTERY TYPE(SPN2566)");
            bit_clr(thiz, F_BMS_RECOGNIZED);
            break;
        }

        if ( thiz->bms.vehicle_info.spn2567_capacity / 10.0f > 1000.0f ) {
            log_printf(WRN,
                   "BMS: BMS not recognized due to invalid CAP INFO(SPN2567)");
            bit_clr(thiz, F_BMS_RECOGNIZED);
            break;
        }

        if ( thiz->bms.vehicle_info.spn2568_volatage / 10.0f > 750.0f ) {
            log_printf(WRN,
                  "BMS: BMS not recognized due to invalid VOLTAGE INFO(SPN2568)");
            bit_clr(thiz, F_BMS_RECOGNIZED);
            break;
        }
        log_printf(DBG_LV2, "BMS: BMS recognized....CAP: %.1f A.H, VOL: %.1f V",
                   thiz->bms.vehicle_info.spn2567_capacity/10.0f,
                   thiz->bms.vehicle_info.spn2568_volatage/10.0);
        if ( ! bit_read(thiz, F_BMS_RECOGNIZED ) ) {
            // send recognized event from here.
        }
        bit_set(thiz, F_BMS_RECOGNIZED);
        break;
    case PGN_BCP :// 0x000600, BMS 配置报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BCP);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        if ( bit_read(thiz, S_BMS_COMM_DOWN) ) {
            log_printf(INF, "BMS: BMS 通信"GRN("恢复"));
        }
        bit_clr(thiz, S_BMS_COMM_DOWN);

        if ( param->buff_payload != 13 ) {
            log_printf(WRN, "BMS: BCP packet size crash, need 13 gave %d",
                       param->buff_payload);
            break;
        }
        memcpy(&thiz->bms.bms_config_info, param->buff.rx_buff,
               sizeof(struct pgn1536_BCP));

        if ( thiz->bms.bms_config_info.spn2816_max_charge_volatage_single_battery /
                100.0f > 24.0f ) {
            log_printf(WRN,
                       "BMS: max_charge_volatage_single_battery out of rang(0-24)"
                       "gave %.2f V (SPN2816)",
             thiz->bms.bms_config_info.spn2816_max_charge_volatage_single_battery /
                       100.0f);
            break;
        }

        if ( thiz->bms.bms_config_info.spn2817_max_charge_current / 10.0f >
             400.0f ) {
            log_printf(WRN, "BMS: max_charge_current out of rang(-400-0)"
                       "gave %.1f V (SPN2816)",
                     thiz->bms.bms_config_info.spn2817_max_charge_current / 10.0f);
            break;
        }

        if ( thiz->bms.bms_config_info.spn2818_total_energy / 10.0f > 1000.0f ) {
            log_printf(WRN, "BMS: total_energy out of rang(0-1000 KW.H)"
                       "gave %.1f KW.H (SPN2818)",
                     thiz->bms.bms_config_info.spn2818_total_energy / 10.0f);
            break;
        }

        if ( thiz->bms.bms_config_info.spn2819_max_charge_voltage / 10.0f >
                750.0f ) {
            log_printf(WRN, "BMS: max_charge_voltage out of rang(0-750 V)"
                       "gave %.1f V (SPN2819)",
                     thiz->bms.bms_config_info.spn2819_max_charge_voltage / 10.0f);
            break;
        }

        log_printf(DBG_LV2, "BMS: BCP done, BSVH: %.2f V, MAXi: %.1f A, "
                   "CAP: %.1f KW.H, MVC: %.1f V, MT: %d, SOC: %.1f %%, V: %.1f V",
                   thiz->bms.bms_config_info.spn2816_max_charge_volatage_single_battery/100.0f,
                   (thiz->bms.bms_config_info.spn2817_max_charge_current-4000)/-10.0f,
                   thiz->bms.bms_config_info.spn2818_total_energy/10.0f,
                   thiz->bms.bms_config_info.spn2819_max_charge_voltage/10.0f,
                   thiz->bms.bms_config_info.spn2820_max_temprature-50,
                   thiz->bms.bms_config_info.spn2821_soc/10.0f,
                   thiz->bms.bms_config_info.spn2822_total_voltage/10.0f);
        break;
    case PGN_BRO :// 0x000900, BMS 充电准备就绪报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BRO);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        log_printf(INF, "BMS is %s for charge.",
                   param->buff.rx_buff[0] == 0x00 ?
                    "not ready" :
                    param->buff.rx_buff[0] == 0xAA ?
                    "ready" : "<unkown status>");
        if ( param->buff.rx_buff[0] == 0x00 ) {
            bit_clr(thiz, F_BMS_READY);
            bit_clr(thiz, F_CHARGER_READY);
        } else if ( param->buff.rx_buff[0] == 0xAA ) {
            bit_set(thiz, F_BMS_READY);
            bit_set(thiz, F_CHARGER_READY);
        } else {
            log_printf(WRN, "BMS: wrong can package data.");
        }
        break;
    case PGN_BCL :// 0x001000, BMS 电池充电需求报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BCL);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        if ( bit_read(thiz, S_BMS_COMM_DOWN) ) {
            log_printf(INF, "BMS: BMS 通信"GRN("恢复"));
        }
        bit_clr(thiz, S_BMS_COMM_DOWN);

        memcpy(&thiz->bms.bms_charge_need_now,
               param->buff.rx_buff, sizeof(struct pgn4096_BCL));
        if ( thiz->bms.bms_charge_need_now.spn3072_need_voltage/10.0f > 750 ) {
            log_printf(WRN, "BMS: spn3072 range 0-750V gave: %d V",
                       thiz->bms.bms_charge_need_now.spn3072_need_voltage);
        } else {
            //thiz->need_V = 10;
            thiz->need_V = thiz->bms.bms_charge_need_now.spn3072_need_voltage/10.0f;
        }
        if ( (thiz->bms.bms_charge_need_now.spn3073_need_current - 4000 )/-10.0f < 0 ) {
            log_printf(WRN, "BMS: spn3073 range -400-0A gave: %d A",
                       thiz->bms.bms_charge_need_now.spn3073_need_current);
        } else {
            thiz->need_I = 0;
            double fi = (thiz->bms.bms_charge_need_now.spn3073_need_current-4000)/10.0;
            fi = fi < 0 ? -fi : fi;
            fi = 400.0 - fi;
            thiz->need_I = fi;
        }

        log_printf(DBG_LV3, "BMS: SETV: %.1f, SETI: %.1f", thiz->need_V, thiz->need_I);

        double fi = (thiz->bms.bms_charge_need_now.spn3073_need_current-4000)/10.0;
        log_printf(INF, "BMS.BCL: need I:  %04X, %d, %d, |(NI - 4000)/10|=%.1f A, GBT: %.1f A",
                   thiz->bms.bms_charge_need_now.spn3073_need_current,
                   thiz->bms.bms_charge_need_now.spn3073_need_current,
                   (unsigned)thiz->bms.bms_charge_need_now.spn3073_need_current,
                   fi < 0 ? -fi : fi,
                   (thiz->bms.bms_charge_need_now.spn3073_need_current-4000)/-10.0
                   );

        log_printf(INF, "BMS: PGN_BCL fetched, V-need: %.1f V, I-need: %.1f mode: %s",
                   thiz->bms.bms_charge_need_now.spn3072_need_voltage/10.0,
                   (thiz->bms.bms_charge_need_now.spn3073_need_current+400)/-10.0f,
                   thiz->bms.bms_charge_need_now.spn3074_charge_mode ==
                    CHARGE_WITH_CONST_VOLTAGE ? "恒压充电" :
                   thiz->bms.bms_charge_need_now.spn3074_charge_mode ==
                        CHARGE_WITH_CONST_CURRENT ? "恒流充电" : "无效模式");
        break;
    case PGN_BCS :// 0x001100, BMS 电池充电总状态报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BCS);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        log_printf(DBG_LV2, "BMS: PGN_BCS fetched.");
        memcpy(&thiz->bms.bms_all_battery_status, param->buff.rx_buff,
               sizeof(struct pgn4352_BCS));
        if (thiz->bms.bms_all_battery_status.spn3075_charge_voltage/10.0 > 750.0f) {
            log_printf(WRN, "BMS: spn3075 range 0-750 gave: %.1f V",
                     thiz->bms.bms_all_battery_status.spn3075_charge_voltage/10.0);
        }
        if (thiz->bms.bms_all_battery_status.spn3076_charge_current/10.0 > 400.0f) {
            log_printf(WRN, "BMS: spn3076 range -400-0 gave: %.1f V",
                   -(thiz->bms.bms_all_battery_status.spn3076_charge_current/10.0));
        }
        if (thiz->bms.bms_all_battery_status.spn3077_max_v_g_number/100.0 > 24.0 ) {
            log_printf(WRN, "BMS: spn3077 range 0-24 gave: %.1f V",
                   -(thiz->bms.bms_all_battery_status.spn3077_max_v_g_number/100.0));
        }
        if (thiz->bms.bms_all_battery_status.spn3078_soc > 100 ) {
            log_printf(WRN, "BMS: spn3078 range 0%%-100%% gave: %d%%",
                   -(thiz->bms.bms_all_battery_status.spn3078_soc));
        }
        log_printf(DBG_LV3, "BMS.BCS: CV: %.1f V, CI: %.1f A, gVmax: %.1f, "
                   "SOC: %d %%, RT: %d min",
                   thiz->bms.bms_all_battery_status.spn3075_charge_voltage/10.0,
                   (thiz->bms.bms_all_battery_status.spn3076_charge_current-4000)/-10.0,
                   (thiz->bms.bms_all_battery_status.spn3077_max_v_g_number&0xFFF)/100.0,
                   thiz->bms.bms_all_battery_status.spn3078_soc,
                   thiz->bms.bms_all_battery_status.spn3079_need_time);
        break;
    case PGN_BSM :// 0x001300, 动力蓄电池状态信息报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BSM);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        log_printf(DBG_LV2, "BMS: PGN_BSM fetched.");
        memcpy(&thiz->bms.bms_battery_status, param->buff.rx_buff,
               sizeof(struct pgn4864_BSM));
        if ( SINGLE_BATTERY_VOLTAGE_HIGH ==
             (thiz->bms.bms_battery_status.remote_single&SINGLE_BATTERY_VOLTAGE_HIGH)){
        }
        if (SINGLE_BATTERY_VOLTAGE_LOW ==
             (thiz->bms.bms_battery_status.remote_single&SINGLE_BATTERY_VOLTAGE_LOW)){

        }

        if (BATTERY_CHARGE_CURRENT_HIGH ==
             (thiz->bms.bms_battery_status.remote_single&BATTERY_CHARGE_CURRENT_HIGH)){

        }
        if (BATTERY_CHARGE_CURRENT_LOW ==
             (thiz->bms.bms_battery_status.remote_single&BATTERY_CHARGE_CURRENT_LOW)){
        }

        if (BATTERY_TEMPRATURE_HIGH ==
                (thiz->bms.bms_battery_status.remote_single&BATTERY_TEMPRATURE_HIGH)){
        }
        if (BATTERY_TEMPRATURE_LOW ==
                (thiz->bms.bms_battery_status.remote_single&BATTERY_TEMPRATURE_LOW)) {
        }

        if (INSULATION_FAULT ==
                (thiz->bms.bms_battery_status.remote_single&INSULATION_FAULT)){
        }
        if (INSULATION_UNRELIABLE==
                (thiz->bms.bms_battery_status.remote_single&INSULATION_UNRELIABLE)){
        }

        if (CONNECTOR_STATUS_FAULT==
                (thiz->bms.bms_battery_status.remote_single&CONNECTOR_STATUS_FAULT)){
        }
        if (CONNECTOR_STATUS_UNRELIABLE==
                (thiz->bms.bms_battery_status.remote_single&CONNECTOR_STATUS_UNRELIABLE)){
        }

        if (CHARGE_ALLOWED==
                (thiz->bms.bms_battery_status.remote_single&CHARGE_ALLOWED)){
        }
        if (CHARGE_FORBIDEN==
                (thiz->bms.bms_battery_status.remote_single&CHARGE_FORBIDEN)){
        }
        break;
    case PGN_BMV :// 0x001500, 单体动力蓄电池电压报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BMV);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        memcpy(&thiz->bms.bms_battery_V, param->buff.rx_buff,
               sizeof(struct pgn5376_BMV));

        log_printf(DBG_LV2, "BMS: PGN_BMV fetched.");
        break;
    case PGN_BMT :// 0x001600, 单体动力蓄电池温度报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BMT);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        memcpy(&thiz->bms.bms_battery_T, param->buff.rx_buff,
               sizeof(struct pgn5632_BMT));

        log_printf(DBG_LV2, "BMS: PGN_BMT fetched.");
        break;
    case PGN_BSP :// 0x001700, 动力蓄电池预留报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BSP);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }

        log_printf(DBG_LV2, "BMS: PGN_BSP fetched.");
        break;
    case PGN_BST :// 0x001900, BMS 中止充电报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BST);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        /*
         * 接收到中止充电报文,充电机发送CTS,并关闭高压输出
         */
        bit_set(thiz, F_PCK_BMS_TRM);
        memcpy(&thiz->bms.bms_bst, param->buff.rx_buff,
               sizeof(struct pgn6400_BST));

        log_printf(INF, "BMS: PGN_BST fetched.");
        break;
    case PGN_BSD :// 0x001C00, BMS 统计数据报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BSD);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        if ( bit_read(thiz, S_BMS_COMM_DOWN) ) {
            log_printf(INF, "BMS: BMS 通信"GRN("恢复"));
        }
        thiz->bms.charge_stage = CHARGE_STAGE_DONE;
        bit_clr(thiz, S_BMS_COMM_DOWN);
        memcpy(&thiz->bms.bms_stop_bsd, param->buff.rx_buff,
               sizeof(struct pgn7168_BSD));
        log_printf(INF, "BMS.BSD: SOC: %d %%, Vmin: %.2f V, Vmax: %.2f V,"
                   "Tmin: %d, Tmax: %d", thiz->bms.bms_stop_bsd.end_soc,
                   thiz->bms.bms_stop_bsd.min_bat_V/100.0f,
                   thiz->bms.bms_stop_bsd.max_bat_V/100.0f,
                   thiz->bms.bms_stop_bsd.min_bat_T - 50,
                   thiz->bms.bms_stop_bsd.max_bat_T - 50);

        log_printf(DBG_LV2, "BMS: PGN_BSD fetched.");
        break;
    case PGN_BEM :// 0x001E00, BMS 错误报文
        gen = gen_search(thiz->bms.generator, thiz->bms.can_pack_gen_nr, PGN_BEM);
        if ( gen ) {
            gen->can_counter ++;
            gen->can_silence = 0;
        }
        if ( param->buff.rx_buff[0] & 0x01 ) {
            log_printf(WRN, "BMS: 接收PSN2560=0x00的报文超时");
        }
        if ( param->buff.rx_buff[0] & 0x02 ) {
            log_printf(WRN, "BMS: 接收PSN2560=0x00的报文不可信");
        }

        if ( param->buff.rx_buff[0] & 0x04 ) {
            log_printf(WRN, "BMS: 接收PSN2560=0xAA的报文超时");
        }
        if ( param->buff.rx_buff[0] & 0x08 ) {
            log_printf(WRN, "BMS: 接收PSN2560=0xAA的报文不可信");
        }

        if ( param->buff.rx_buff[1] & 0x01 ) {
            log_printf(WRN, "BMS: 接收CTS和CML的报文超时");
        }
        if ( param->buff.rx_buff[1] & 0x02 ) {
            log_printf(WRN, "BMS: 接收CTS和CML的报文不可信");
        }

        if ( param->buff.rx_buff[1] & 0x04 ) {
            log_printf(WRN, "BMS: 接收充电机完成充电准备的报文超时");
        }
        if ( param->buff.rx_buff[1] & 0x08 ) {
            log_printf(WRN, "BMS: 接收充电机完成充电准备的报文不可信");
        }

        if ( param->buff.rx_buff[2] & 0x01 ) {
            log_printf(WRN, "BMS: 接收充电机状态的报文超时");
        }
        if ( param->buff.rx_buff[2] & 0x02 ) {
            log_printf(WRN, "BMS: 接收充电机状态的报文不可信");
        }

        if ( param->buff.rx_buff[2] & 0x04 ) {
            log_printf(WRN, "BMS: 接收充电机中止充电的报文超时");
        }
        if ( param->buff.rx_buff[2] & 0x08 ) {
            log_printf(WRN, "BMS: 接收充电机中止充电的报文不可信");
        }

        if ( param->buff.rx_buff[3] & 0x01 ) {
            log_printf(WRN, "BMS: 接收充电机充电统计的报文超时");
        }
        if ( param->buff.rx_buff[3] & 0x02 ) {
            log_printf(WRN, "BMS: 接收充电机充电统计的报文不可信");
        }

        log_printf(DBG_LV2, "BMS: PGN_BEM fetched.");
        break;
    default:
        log_printf(WRN, "BMS: un-recognized PGN %08X",
                   param->can_id);
        break;
    }
    return ERR_OK;
}