@@ -558,6 +558,20 @@ ATCA_STATUS calib_write_config_counter(ATCADevice device, uint16_t counter_id, u
558558
559559 return status ;
560560}
561+
562+ ATCA_STATUS calib_write_config_counter_ext (ATCADevice device , uint16_t counter_id , uint32_t counter_value )
563+ {
564+ #if CALIB_ECC204_EN
565+ if (ECC204 == atcab_get_device_type_ext (device ))
566+ {
567+ return calib_ecc204_write_config_counter (device , (uint8_t )counter_id , (uint16_t )counter_value );
568+ }
569+ else
570+ #endif
571+ {
572+ return calib_write_config_counter (device , counter_id , counter_value );
573+ }
574+ }
561575#endif /* CALIB_WRITE_EN */
562576
563577/** \brief Execute write command to write either 16 byte or 32 byte to one of the EEPROM zones
@@ -706,7 +720,53 @@ ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, const uint8_t* con
706720
707721 return status ;
708722}
709- #endif /* CALIB_WRITE_EN */
723+
724+ /** \brief Initialize monotonic counters in device with a specific value.
725+ *
726+ * The monotonic counters are stored in the configuration zone using a special
727+ * format. This encodes a binary count value into the 16 byte encoded value
728+ * required. Can only be set while the configuration subzone 2 is unlocked.
729+ *
730+ * \param[in] device Device context pointer
731+ * \param[in] counter_id Counter_id should always be 0.
732+ * \param[in] counter_value Counter value to set.
733+ *
734+ * \return ATCA_SUCCESS on success, otherwise an error code.
735+ */
736+ ATCA_STATUS calib_ecc204_write_config_counter (ATCADevice device , uint8_t counter_id , uint16_t counter_value )
737+ {
738+ uint16_t bin_a , bin_b ;
739+ uint64_t lin_a , lin_b ;
740+ uint8_t bytes [16 ];
741+ ATCA_STATUS status = ATCA_GEN_FAIL ;
742+
743+ if (counter_id != 0 || counter_value > ECC204_COUNTER_MAX_VALUE )
744+ {
745+ return ATCA_TRACE (ATCA_BAD_PARAM , "Invalid counter id or counter value received" );
746+ }
747+
748+ bin_a = (uint16_t )(counter_value / 96 );
749+ bin_b = (counter_value >= 48 ) ? ((uint16_t )((counter_value - 48 ) / 96 )) : 0 ;
750+ lin_a = 0xFFFFFFFFFFFF >> (counter_value % 96 );
751+ lin_b = 0xFFFFFFFFFFFF >> ((counter_value >= 48 ) ? (counter_value - 48 ) % 96 : 0 );
752+
753+ bin_a = ATCA_UINT16_HOST_TO_BE (bin_a );
754+ memcpy (& bytes [0 ], & bin_a , 2 );
755+
756+ bin_b = ATCA_UINT16_HOST_TO_BE (bin_b );
757+ memcpy (& bytes [2 ], & bin_b , 2 );
758+
759+ lin_a = ATCA_UINT64_HOST_TO_BE (lin_a ) >> 16 ;
760+ memcpy (& bytes [4 ], & lin_a , 6 );
761+
762+ lin_b = ATCA_UINT64_HOST_TO_BE (lin_b ) >> 16 ;
763+ memcpy (& bytes [10 ], & lin_b , 6 );
764+
765+ status = calib_ecc204_write_zone (device , ATCA_ZONE_CONFIG , 2 , 0 , counter_id , bytes , sizeof (bytes ));
766+
767+ return status ;
768+ }
769+ #endif /* CALIB_WRITE_ECC204_EN */
710770
711771#if CALIB_WRITE_ENC_EN && defined(ATCA_ECC204_SUPPORT )
712772/** \brief Executes write command, performs an encrypted write of a 32 byte block into given slot.
0 commit comments