Здравствуйте!

Пытаюсь связать между собой HCS200 и HCS515, но пока безуспешно..
Т.е. имеется HCS515 подключенный к AVR, и купленный брелок с HCS200.

Програма для AVR была взята с аппноута AN714 - там есть все функции для работы с 515 кроме программирования мануфактурника с конф. байта.

Для теста были взяты следующие значения (получены программой KeeloqTool):
Manufacturer's Code - 0x0123456789ABCDEF
Serial Number - 0x1234567
Encryption Key - 0x0516FBE989074278



На данный момент программирование мануфактурника выглядит следующим образом:

Код
byte manuf_key[] = {0xEF,0xCD,0xAB,0x89,0x67,0x45,0x23,0x01};

char Command_Mode( char decoder_command, char cmd_byte1, char cmd_byte2 )
{
  
    byte bit_counter;
    byte temp_buffer;
  
    treq_timeout = 0x0000; // initialize union variable (integer element)
    
    TRISDATA_IN; // ensure data direction pin state is input
    HCSCLK_HIGH; // set clock high to initiate command
    TRISCLK_OUT; // ensure data direction pin state is output
    
    do // loop until HCS515 responds (1 loop = 33uS)
    { // or until ~500mS expires (total loop 660mS)
      delay_us(100); // ~24uS delay
      treq_timeout++; // increment response wait timer
      if ( GET_HCSDATA ) // has HCS515 responded ?
        treq_timeout = TREQ +1; // if so then set timeout expiration
    } while ( treq_timeout <= TREQ );
    
    if ( GET_HCSDATA == 0 ) // is data line still low?    
      return ( TREQ_ERR ); // return with error code

    // At this point the HCS515 has responded by asserting data line high
    // so bring the clock low
    delay_us(100); // (Tresp, spec-20uS(min)) ~42uS delay
    HCSCLK_LOW; // bring clock low, ack to decoder
    
    // At this point, HCS515 has acknowledged PICmicro by negating data line (low)
    delay_us(100); // Tstart (20uS min) ~ 41.50uS delay
    TRISDATA_OUT; // ensure data direction pin state is output
    bit_counter = 8; // initialize bit counter    
    temp_buffer = decoder_command; // assign command to temp_buffer
  
    do
    {
      if (temp_buffer & 1) // test if carry bit set
        HCSDATA_HIGH; // set data line high
      else      
        HCSDATA_LOW; // set data line low
      
      temp_buffer >>= 1; // rotate LSB
      
      HCSCLK_HIGH; // set clock high
      delay_us(100); // ~23.5uS delay
      HCSCLK_LOW; // set clock low( data sampled on falling edge )
      delay_us(100); // ~23.5uS delay (also provides for required Tds)
    } while ( --bit_counter ); // decrement counter and test if complete
    
    if ( cmd_byte2 == PROGRAM ) // test if Write EE is using command mode function
      return ( NO_ERROR );
    
    bit_counter = 8; // initialize bit counter
    temp_buffer = cmd_byte1; // 1st byte after command byte to temp_buffer
    do
    {
      
      if (temp_buffer & 1) // test if carry bit set
        HCSDATA_HIGH; // set data line high      
      else    
        HCSDATA_LOW; // set data line low
      
      temp_buffer >>= 1; // rotate LSB
      
      HCSCLK_HIGH; // set clock high
      delay_us(100); // ~20uS delay
      HCSCLK_LOW; // set clock low ( data sampled on falling edge )
      delay_us(100); // ~20uS delay ( also provides for required Tds)
    } while ( --bit_counter ); // decrement counter and test if complete

    if ( cmd_byte2 == WRITE ) // test if Write EE is using command mode function
      return ( NO_ERROR );
    
    bit_counter = 8; // initialize bit counter
    temp_buffer = cmd_byte2; // 2nd byte after command byte to temp_buffer
    
    do
    {
      if (temp_buffer & 1) // test if carry bit set
        HCSDATA_HIGH; // set data line high      
      else      
        HCSDATA_LOW; // set data line low
      
      temp_buffer >>= 1; // rotate LSB
      
      HCSCLK_HIGH; // set clock high
      delay_us(100); // ~20uS delay
      HCSCLK_LOW; // set clock low( data sampled on falling edge )
      delay_us(100); // ~20uS delay ( also provides for required Tds)
    } while ( --bit_counter ); // decrement counter and test if complete
    
    return ( NO_ERROR ); // return with no error
}



char Learn( void )
{
    byte tack_timeout;
    byte temp;
    
    //flag1.learn_entered = 0; // reset learn entered flag
    temp = Command_Mode( ACTIVE_LRN, DUMMY, DUMMY ); // initiate command mode
    if ( temp != 0 )
      return ( temp ); // return with error code
    
    // At this point Command Mode for Learn has been sent to HCS515, wait for acknowledge
    // HCS515 should respond within 20uS (max) after clock line is asserted
    TRISDATA_IN; // ensure data direction pin state is input
    delay_us(50); // wait for ~ 40uS (Tlrn-20uS(min) Tlrn )
    HCSCLK_HIGH; // set clock high, begin TACK period
  
    tack_timeout = 0x00; // initialize variable
    do // loop until HCS515 responds with
    { // data line high or until time expires
      // loop time ~8uS (total: 5*8us= 40uS)
      delay_us(10);
      tack_timeout++; // increment timeout counter
      if ( GET_HCSDATA == 1 ) // has HCS515 responded and entered learn mode ?
        tack_timeout = TACK_LRN +1;// if so then set timeout expiration      
    } while ( ( GET_HCSDATA != 1 ) && ( tack_timeout <= TACK_LRN ) );
    
    if ( GET_HCSDATA != 1 ) // is DATA line still low after TACK    
      return ( TACK_LRN_ERR ); // return with error code
    
    delay_us(25); // ~22uS delay (Tresp spec 20-1000uS)
    HCSCLK_LOW; // set clock low
    delay_us(25); // ~22uS delay (TACK2 spec 10uS max)
    
    //flag1.learn_entered = 1; // set flag learn entered mode
    return ( NO_ERROR ); // return with no error condition
}






char Program(byte * manuf_key, byte conf_byte )
{
    byte temp;
    byte bit_counter;
    byte temp_buffer;
    byte tack_timeout;
    byte i;
    byte buff[9];
    
    buff[0] = conf_byte;
    for (i=1; i<9; i++)
      buff[i] = manuf_key[i-1];
  
    temp = Command_Mode( PROGRAM, DUMMY, PROGRAM ); // initiate command mode
    if ( temp != 0 )
      return ( temp ); // return with error code
  
    for(i=0; i<9; i++)
    {
      TRISDATA_OUT; // ensure data direction pin state is output
      bit_counter = 8; // initialize bit counter
      temp_buffer = buff[i]; // assign data to temp_buffer
      
      do
      {
        if (temp_buffer & 1) // test if carry bit set
          HCSDATA_HIGH; // set data line high
        else      
          HCSDATA_LOW; // set data line low
        
        temp_buffer >>= 1; // rotate LSB
        
        HCSCLK_HIGH; // set clock high
        delay_us(50); // ~22uS delay
        HCSCLK_LOW; // set clock low ( data sampled on falling edge )
        delay_us(50); // ~22uS delay ( also provides for required Tds )
      } while ( --bit_counter ); // decrement counter and test if complete
      
      HCSDATA_LOW; // set data line low
      delay_us(100); // wait for ~ 20uS      
      
    }
    
      TRISDATA_IN; // set pin direction for input
    
      HCSCLK_HIGH; // set clock high, begin TACK period
      delay_us(3000); // wait here 3mS to start
      //delay_us(100);
      tack_timeout = 0;//0x40; // initialize variable
      
      do // loop until HCS515 responds (1 loop = 48uS)
      { // or until ~9mS expires
        delay_us(3000); //~41uS delay
        //delay_us(1000);
        tack_timeout++; // increment timeout counter
        
        if ( GET_HCSDATA == 1 ) // has HCS515 responded ?
          tack_timeout = TACK_WR +1;// if so then set timeout expiration      
      } while ( tack_timeout <= TACK_WR );
      delay_us(25); // ~20uS delay (Tresp)
      HCSCLK_LOW; // set clock low
      delay_us(25); // ~20uS delay (TACK2 wait)
      //manuf_key++; // increment data pointer
    
      
      
    TRISDATA_IN; // ensure data direction pin state is input
    delay_us(1000);
    
    return ( NO_ERROR ); // return with no error condition
}


void Prog_test(void)
{
  Program(manuf_key, 0 );  
}



Связь с HCS151 в норме - по крайней мере удалось корректно записать/вычитать User EEPROM


//////////////////////////////////////

Теперь по части HCS200.

EEPROM шью с помощью программатора ChipProg-2.
При прошивке программатор говорит что все ок.

Структура EEPROM HCS200 имеет следующий вид:

WORD ADDRESS MNEMONIC DESCRIPTION
0 KEY_0 64-bit crypt key (word 0) LSb’s
1 KEY_1 64-bit crypt key (word 1)
2 KEY_2 64-bit crypt key (word 2)
3 KEY_3 64-bit crypt key (word 3) MSb’s
4 SYNC 16-bit synchronization value
5 Reserved Set to 0000H
6 SER_0 Device Serial Number (word 0) LSb’s
7 SER_1 Device Serial Number (word 1) MSb’s
8 SEED_0 Seed Value (word 0)
9 SEED_1 Seed Value (word 1)
10 Reserved Set to 0000H
11 CONFIG Configuration Word


Исходя из этого, подготовил следующий файл для программатора:

///////////////////
1.hex
0x78, 0x42, 0x07, 0x89, 0xE9, 0xFB, 0x16, 0x05, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01,
0x4D, 0x3C, 0x2B, 0x1A, 0x00, 0x00, 0x67, 0x05



После прошивки брелка, в HCS515 посылается комманда Learn, после чего несколько раз нажимаю одну из кнопок на брелке, но HCS515 никак не реагирует на эту посылку (должна дергать линией DATA, после чего AVR должна принять описание запомненого енкодера).

Также в stand-alone режиме обучения никаких успехов (подтягиваем CLOCK к верхнему уровню, 2 секунды горит светодиод подключенный к DATA, когда светодиод гаснет отпускаем кнопку и жмем несколько раз на кнопку брелка).

Подскажите плз в чем может быть ошибка.