Serial Communication Classification Protocol (SCCP) allows for an IEEE 802.3cg, Single-pair Power over Ethernet (SPoE) compliant Power Sourcing Equipment (PSE) to classify a compliant Powered Device (PD) before power is applied to a cable. Through SCCP, information on device class, type, pd_faulted, and Cable resistance measurements enabled/disabled can be obtained.
This Wiki provides an application circuitry overview, SCCP transactions overview, sample C code SCCP implementation, evaluation guidance and reference material for class and type. The sample C code may be used as a starting point for integrating SPoE power management into a system host microcontroller.
The SCCP was derived from the 1-Wire® protocol and utilizes a half-duplex, bi-directional open-drain bus where the PSE or PD can pull-down. Figure 1 illustrates an SPoE system featuring the LTC4296-1 PSE, the LTC9111 PD, an application host microcontroller, and ADIN1100 10BASE-T1L PHYs. Only one of five LTC4296-1 ports is shown, and the “x” suffix denotes pin names as a function of port number.
The LTC4296-1 SCCP related components include pulldown MOSFET M3, line sense NPN BJT transistor Q1, snubber disconnect MOSFET M2, the LTC4296-1 SWx pin, and the host microcontroller GPOx and GPIx pins. The microcontroller's GPOx pin drives M3 to pulldown the line voltage while Q1 limits the maximum voltage sensed at the GPIx pin. Snubber R3/C4 is provided for loop stability during inrush and current limit of high-side MOSFET M1 and is disconnected during PD detection and SCCP. Secondary snubber R5/C5 prevents excess ringing at the OUTPx pin when snubber R3/C4 is disconnected.
Microcontroller requirements for implementing SCCP are:
At the PSE, the LTC4296-1 is set up for the classification state by the microcontroller. Classification is configured by setting the software PSE ready bit (PxCFG0, Bit6, SW_PSE_READY) and the classification mode bit (PXCFG0, Bit 13, SET_CLASSIFICATION_MODE) before entering the detection state. If the microcontroller determines a valid PD with a compatible class is present, the port can proceed to the power-up state by setting the port software power available bit (Register PxCFG0, Bit 5, SW_POWER_AVAILABLE) and the end classification bit (Register PxCFG0, Bit 14, END_CLASSIFICATION). Further description of port states can be found in the LTC4296-1 Datasheet.
On the PD side, the LTC9111 detects the SCCP logic states on the lines through SNS1 and SNS2 and uses external MOSFETs (M13/M14) to pull-down the port voltage during classification in order to transmit a logic low. The use of two external MOSFETs allows successful classification regardless of input connector polarity configuration.
Figure 1. SPoE System
SCCP transactions are comprised of initialization, write slot, and read slot protocols. The PSE initiates all protocols by pulling down the bus. The PSE also provides a voltage limited pull-up current to restore the bus voltage to a logic high. The PD uses the rectified voltage from the PSE pull-up to retain state during pull-down events. Table 1 summarizes the basic SCCP protocols, and Figure 2-4 illustrates the corresponding waveforms.
Operation | Description | Implementation |
---|---|---|
Initialization | Reset and detect the PD | PSE pulls bus low, delays tRSTL, releases bus, waits tMSP to sample PD pulse (Figure 2) |
Write Slot (1) | Send a '1' bit to the PD | PSE pulls bus low, delays tW1L, releases bus (Figure 3) |
Write Slot (0) | Send a '0' bit to the PD | PSE pulls bus low, delays tW0L, releases bus (Figure 3) |
Read Slot | Read a '0' or '1' bit from the PD | PSE pulls bus low, delays tW1L, releases bus, samples bus at tMSR (Figure 4) |
Table 1. SCCP Protocols
The PSE initiates the SCCP transaction by pulling down on the bus during the reset pulse. After which the PD responds with a pull-down presence pulse. During the reset pulse, the PSE pulls down on the bus voltage below the input logic low voltage, VTL (2V PSE, 1V PD), for reset time low time, tRSTL (8ms-10.5ms).
Once the PSE releases the bus, the PD detects the rising edge cross the input logic high voltage VTH (3V) and waits the presence-detect high time, tPDH (0.7ms-1.3ms), before transmitting a presence pulse. The PSE samples for the PD presence pulse by tMSP (1.8ms-2.2ms). The PD holds the presence pulse for the presence-detect low time, tPDL (2.8ms-5.2ms).
Figure 2. SCCP Initialization
The duration of the write time slot for either a '0' or '1' should last for a maximum of tWRITESLOT (2.78ms). When the PSE writes a '0' to the PD, first the PSE pulls down the bus voltage below the VTL, then the PSE releases within the write 0 low time, tW0L (1.8ms-2.2ms), as seen in Figure 3. In the case where the PSE aims to write a '1', the PSE pulls down on the bus voltage, and then it releases the line within the write 1 low time, tW1L (0.09ms-0.61ms), as illustrated in Figure 3.
Figure 3. SCCP Write Time Slot
The PSE initiates the read time slot by pulling low on the bus. Subsequently, the PSE releases the bus within tW1L, at which point the PD responds by pulling the bus low for the read 0 low time, tR0L (1.75ms-3.25ms), in order to transmit a '0' (Figure 4). Alternatively, if the intention is to transmit a '1', the PD refrains from pulling the bus low after the read 1 low time, tW1L . The PD sends data LSB first. Each of these read time slots has a maximum duration of tREADSLOT (3.83ms).
Figure 4. SCCP Read Time Slot
Following an Initialization Sequence or a Write/Read Time Slot, there is a recovery time of tREC (0.27ms-0.33ms). This recovery time begins from the moment the PSE OUTPx voltage exceeds the VTH threshold and extends until the bus voltage begins to get pulled down. Additionally, the bus voltage during any transaction must have a rise time from GND to VTH within tR (0.025ms-0.5ms). It must have a fall time from VPUP (4.7V-5.5V) to VTL within tF (0.025ms-0.25ms). The PD Reservoir Capacitor Recharge Time, denoted as tCHRG, extending from when the voltage on the bus crosses the VCHRG threshold (4.23V) to the commencement of the bus voltage being pulled down, must exceed 0.2ms.
Figure 5 illustrates a basic example SCCP transaction. The two waveforms are:
Note SCCP data is read/written LSB first, low byte first.
The basic SCCP transaction is comprised of:
i. Initialization
ii. Write Broadcast Address (0xAA)
iii. Write Read_Scratchpad Command (0xCC)
iv. Read PD CLASS_TYPE_INFO Low Byte
v. Read PD CLASS_TYPE_INFO High Byte
vi. Read PD CRC Byte
Calculating CRC9 (PEC) Value
Figure 5. SCCP Transaction
Table 2 shows the bit information from the CLASS_TYPE_INFO register bytes. Refer to the Appendix for Class and Type listing tables.
Table 2. CLASS_TYPE_INFO Register Bytes Table
Example C code for send_reset_pulse() is shown in Figure 6. The send_reset_pulse() function returns an unsigned 8-bit integer which corresponds to the logic level of the voltage sampled by the PSE after delay tMSP.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). *Function: uint8_t send_reset_pulse() *This function sends a reset pulse and searches for PD presence pulse. Reset pulse *utilizes the sccp timer to incorporate the timings as defined in IEEE 802.3cg *standard * *uint8_t value of PD presence pulse voltage is returned * ******************************************************************************************************************/ uint8_t send_reset_pulse() { /* assert pulse */ PULL_DOWN_LINE(); TimerDelay_ms(3); /* wait 3ms to see if GPIx went low */ /* check GPIx voltage is low to protect pull-down fet from stuck high faults */ if(READ_LINE()) { RELEASE_LINE(); /* deassert GPOx if mosfet was unable to pull down */ LED1_ON(); /* and turn on red LED to indicate fault */ } else { LED1_OFF(): /* make sure the red LED is off */ } TimerDelay_msf(T_RSTL_NOM-3); /* continue pulling-down if no fault */ RELEASE_LINE(); /* stop puling-down */ TimerDelay_msf(T_MSP); /* wait for pull-up to restore line voltage and then PD to pull-down with presence pulse */ uint8_t level = READ_LINE(); /* look for PD presence pulse */ TimerDelay_msf(3.22); /* wait for PD to stop pulling-down and pull-up to restore line voltage */ return !level; }
Figure 6. Initialization Example C Code
Example C code for write_bit() is shown in Figure 7. Unlike the initialization sequence, no special precatuion is needed to protect the pulldown MOSFET against stuck-high faults since the write time for a 0 bit (tW0L) is less than 3ms.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). * Function: void write_bit(uint8_t bit) * * This function controls the pulldown FET to send a bit of a SCCP * transaction to the PD * ******************************************************************************************************************/ void write_bit(uint8_t bit) { TimerDelay_resetCount(); /* timer->CNT = 0 */ PULL_DOWN_LINE(); if (bit) { TimerDelay_msf(T_W1L); } else { TimerDelay_msf(T_W0L); } RELEASE_LINE(); while(TIMERDELAY_ellapsedUsec() < T_WRITESLOT*1000); /*elapsed time in us since timer count reset */ return; }
Figure 7. Write Bit Example C Code
Example C code for the read_bit() function is shown in Figure 8. The read_bit() function returns the logical value of the bus voltage read from the PD at tMSR.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). * Function: uint8_t read_bit() * This function implements the GPO pulse sequence required to receive and read a bit * on GPI and return the result. * ******************************************************************************************************************/ uint8_t read_bit() { TimerDelay_resetCount(); /* timer->CNT = 0 PULL_DOWN_LINE(); TimerDelay_msf(T_W1L); RELEASE_LINE(); /*wait to get withing read window */ while(TimerDelay_ellapsedUsec() < T_MSR*1000); /*elapsed time in us since timer /*count reset volatile uint8_t bit = READ_LINE(); if(!bit) /* if bit was a 0, need to wait for release of line then allow for */ /* enough recovery time (T_REC) { while(!READ_LINE() && ( TimerDelay_ellapsedUsec() < T_READSLOT_MAX_TYPE_E*1000) ); /* wait until PD releases or t-readslot_max uint32_t t_release; /* declare time it takes PD to release as t_release if(READ_LINE()) // pd released in time { t_release = TimerDelay_ellapsedUsec(); } else // pd failed to release before t_readslot_max so just return bit { return bit; } // wait for t_rec uint32_t ellapsed_trec = 0; /* define vars for trec uint32_t ellapsed_slot = 0; do { ellapsed_slot = TimerDelay_ellapsedUsec(); ellapsed_trec = ellapsed_slot - t_release; } while( (ellapsed_trec < T_REC*1000) && (ellapsed_slot < T_READSLOT_MAX_TYPE_E*1000) ); /* we've now either waited for t_rec, or reached t-readslot_max } while(TimerDelay_ellapsedUsec() < T_READSLOT_MAX_TYPE_E*1000); return bit; }
Figure 8. Read Bit Example C Code
The example code in Figure 9 defines Class and Type codes as well as the PSE/PD class compatibility matrix for interpreting the CLASS_TYPE_INFO word.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). * global variable: const uint8_t class_compatibility[16][16] * This is 2 dimensional array returns the compatibility of PSE with PD class * Following an SCCP transaction class_compatibility[x][y] variable contains * compatibility of PSE class x with PD class y * * * uint16_t sccp_classes[16] should return the sccp class code associated with each * class. sccp_classes[x] contains the class code associated with class x. * * Similarly sccp_types[x] should return the type code associated with type x. * * CLASS_TYPE_INFO returned from PD should have bits[9:0] consisting of class code * and bits[15:12] consisting of type code. * ******************************************************************************************************************/ /* PSE to PD class compatibility matrix as defined by IEEE 802.3bu/cg */ const uint8_t class_compatibility[16][16] = { /* PSE class /*PD 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 /*0*/ 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /*1*/ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /*2*/ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /*3*/ 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /*4*/ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 /*5*/ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 /*6*/ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 /*7*/ 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 /*8*/ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 /*9*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 /*10*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 /*11*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0 /*12*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 /*13*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1 /*14*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1 /*15*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; /* bottom 12 bits of CLASS_TYPE_INFO codes for PD power classes o through 15 */ uint16_t sccp_classes[16] = { 0x3FE, //class 0 0X3FD, //class 1 0X3FB, //class 2 0X3F7, //class 3 0X3EF, //class 4 0X3DF, //class 5 0x3BF, // class 6 0x37F, // class 7 0x2FF, // class 8 0x1FF, // class 9 0x001, // class 10 0x002, // class 11 0x003, // class 12 0x004, // class 13 0x005, // class 14 0x006, // class 15 }; /* top 4 bits of CLASS_TYPE_INFO register for PD types A through E */ /* A, B, C, D, E */ const uint8_t sccp_types[5] = { 0xE, 0xD, 0xB, 0x7, 0xC }; /*********************************************************************************** * * Function: int index_of(uint16_t val, uint16_t* buf, uint16_t buf_len) * * data bits parsed from SCCP_CLASS_INFO are interpreted for respective class and * type through this function. * ***********************************************************************************/ int index_of(uint16_t val, uint16_t* buf, uint16_t buf_len) { uint16_t i; for(i=0; i<buf_len; i++) { if(buf[i] == val) return (int)i; } return -1; }
Figure 9. Example Code for Class, Type, and PSE/PD Compatibility Matrix Definition
Figure 10 shows example code for transmit_byte(). The transmit_byte() function accepts a byte and uses the write_bit() protocol function to transmit the passed tx_byte to the PD.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). *Function: void transmit_byte(uint8_t tx_byte) *Byte to be transmitted is passed on to this function * *******************************************************************************************************************/ void transmit_byte(uint8_t tx_byte) { uint8_t bit_pos = 0; while (bit_pos < 8) { uint8_t bit = (tx_byte>>bit_pos) & 0x01; write_bit(bit); bit_pos++; } return; }
Figure 10. Example Code for transmit_byte()
Figure 11 shows example code for receive_response(). The receive_response() function utilizes the read_bit() protocol function to receive 2 bytes of CLASS_TYPE_INFO data plus a CRC byte from the PD. The resulting bytes are stored at the address of the passed *buf pointer.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). * Function: void receive_response(uint8_t* buf) * Utilizes 'uint8_t read_bit()' to receive 2 bytes of data plus CRC byte from the PD * *******************************************************************************************************************/ void receive_response(uint8_t* buf) { uint8_t rx_byte = 0, bytes_rxd=0, bit_pos = 0; while (bytes_rxd < 3) { rx_byte = 0; bit_pos = 0; while(bit_pos < 8) { uint8_t bit = read_bit(); rx_byte |= (bit<<bit_pos); bit_pos++; } buf[bytes_rxd] = rx_byte; bytes_rxd++; //TimerDelay_ms(5); /* wait 5ms before reading the next byte, used for internal debugging */ } return; }
Figure 11. Example Code for receive_response()
Figure 12 shows example code for sccp_read_register(). The sccp_read_register() intializes the bus, checks for a PD presence pulse, writes the broadcast address command byte (0xCC) followed by the passed read command byte (cmd), and then reads two bytes of PD data plus the CRC byte. The PD data bytes plus CRC byte are stored at the address of the passed *buf pointer.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). * Function: uint8_t sccp_read_register(uint8_t cmd, uint8_t* buf) * This function sends the required bytes of SCCP to the PD and receives the response * *******************************************************************************************************************/ uint8_t sccp_read_register(uint8_t cmd, uint8_t* buf) { uint8_t present = send_reset_pulse(); if (!present) return 0; /* PD must respond to reset pulse with presence pulse */ //TimerDelay_ms(5); /* line stays high for 5ms, used for internal debugging */ transmit_byte(CMD_BROADCAST_ADDR); /* PSE sends broadcast address 0xCC */ //TimerDelay_ms(5); /* line stays high for 5ms, used for internal debugging */ transmit_byte(cmd); /* PSE sends read command (0xAA, 0xBB, 0x77, or 0x81) */ //TimerDelay_ms(5); /* line stays high for 5ms, used for internal debugging */ receive_response(buf); /* read 2 bytes of register data plus CRC byte */ return 1; }
Figure 12. Example Code for sccp_read_register()
Figure 13 shows example code for get_crc(). The get_crc() function returns the expected CRC byte based on two bytes of data stored at the address of the passed *buf pointer. The CRC calculation is based on the generator polynomial G(x) = x8 + x5 + x4 + 1.
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). * Function: uint8_t get_crc(uint8_t* buf) * SCCP bytes * *******************************************************************************************************************/ uint8_t get_crc(uint8_t* buf) { uint8_t byte, bit; uint8_t x3,x4,x7, in; uint8_t crc = 0; for(byte=0; byte<2; byte++) { for(bit=0; bit<8; bit++) { /* save some bits before shifting register */ x3 = (crc>>3) & 0x01; x4 = (crc>>4) & 0x01; x7 = (crc>>7) & 0x01; in = (buf[byte] >> bit) & 0x01; in ^= x7; /* shift the register */ crc = (crc<<1) | in; /* clear bits 4 & 5 */ crc &= ~(0x30); /* replace bits with xor of 'in' and prev bit */ uint8_t temp = x3 ^ in; crc |= (temp<<4); temp = x4 ^ in; crc |= (temp<<5); } } return crc; }
Figure 13. Example Code for Calculating CRC Byte from 16 Bit PD Data
Figure 14 provides example code sccp_do_class() for implementing detection, SCCP, and then power-up one or more ports when the PSE and PD and PSE classes are compatible. The code assumes intialization of the following peripherals:
Outline of sccp_do_class():
/****************************************************************************************************************** Copyright © 2023 by Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. This software is provided on an "as is" basis without any representations, warranties, guarantees or liability of any kind. Use of the software is subject to the terms and conditions of the Clear BSD License (https://spdx.org/licenses/BSD-3-Clause-Clear.html). *Function: sccp_do_class() *This function incorporates the SCCP using the functions described in previous sections. * *Other functions used in this routine: *uint8_t LTC4296_pseStatus(uint8_t port): This function takes port number as the *argument and returns the pse status of that port. SPI read command to read port status *register is executed. *uint16_t LTC4296_readRegister(uint8_t address): This function returns value at the *specified register from LTC4296-1 SPI registry. A SPI read command is incorporated. * *void LTC4296_writeRegister(uint8_t address, uint16_t value): The value specified is *written and the specified register address. This function incorporates a SPI write *command. * *Further this function assumes that the pse sccp information per port is already known. *Port_class[n] contains sccp class and type of port n * ********************************************************************************************************************/ void sccp_do_class() { uint8_t atLeastOneClassPort = 0; uint8_t port; for(port=0; port<5; port++) { if(port_supports_class[port]) { atLeastOneClassPort = 1; break; } } if(!atLeastOneClassPort) { return; } /* disable write protection */ LTC4296_writeRegister(REG_GCMD, 5); for(port=0; port<5; port++) { if(port_supports_class[port]) { set_active_port(port); /* if pse_status == 2 or 1 (delivering or sleeping), skip this port, it's already powered up */ volatile PseStatus pse_status = LTC4296_pseStatus(port); if(pse_status == PSE_STATUS_DELIVERING || pse_status == PSE_STATUS_SLEEPING || pse_status == PSE_STATUS_UNKNOWN) { continue; // next port } /* if port is not enabled or in idle, enable it and set tdet_disable and set_classification_mode */ uint16_t pncfg0_old = LTC4296_readRegister(REG_P0CFG0+0x10*port); LTC4296_writeRegister(0x13+0x10*port, 0x41 | (1<<11) | (1<<13)); /* wait for pse_status == 3 (searching/detection) */ pse_status = LTC4296_pseStatus(port); uint32_t t0 = HAL_GetTick(); while(pse_status != PSE_STATUS_SEARCHING && pse_status != PSE_STATUS_DELIVERING) { if(HAL_GetTick() - t0 > 4000) { pncfg0_old &= ~(1<<5); // clear pwr_avail LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old); LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old | (1<<14)); //set end_classification bit return; } pse_status = LTC4296_pseStatus(port); } // Tdet additions uint32_t t_det_start = TimerDelay_getCount(); uint32_t t_hold_start = TimerDelay_getCount(); uint32_t t_hold = 0; uint16_t port_status_reg = LTC4296_readRegister(REG_P0ST + 0x10 * port); uint8_t port_det_sign = (port_status_reg & 0x3000) >> 12; uint8_t valid_sign = 0; while (TimerDelay_getCount() - t_det_start < 3100) { port_status_reg = LTC4296_readRegister(REG_P0ST + 0x10 * port); port_det_sign = (port_status_reg & 0x3000) >> 12; if (port_det_sign == 0) { t_hold = t_hold + (TimerDelay_getCount() - t_hold_start); } else { t_hold = 0; t_hold_start = TimerDelay_getCount(); } if (t_hold > 1000) { valid_sign = 1; } } uint8_t sccp_buf[3]; TimerDelay_ms(30); // read scratchpad and parse type and class uint8_t pd_present = sccp_read_register(CMD_READ_SCRATCHPAD, sccp_buf); if(!pd_present) { pncfg0_old &= ~(1<<5); // clear pwr_avail LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old); LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old | (1<<14)); /* set end_classification bit */ continue; /* next port */ } uint16_t scratchpad = (uint16_t)(sccp_buf[1]) << 8; scratchpad |= (uint16_t)(sccp_buf[0]); uint16_t pd_class_code = scratchpad & 0x3FF; int pd_class_num = index_of(pd_class_code, sccp_classes, 16); int pse_class_num = index_of(port_class[port], sccp_classes,16); if(pse_class_num < 0 || pd_class_num < 0 || pse_class_num > 15 || pd_class_num > 15 || (get_crc(sccp_buf) != sccp_buf[2])) { /* port hasn't been configured properly */ pncfg0_old &= ~(1<<5); /* clear pwr_avail */ LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old); LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old | (1<<14)); /* set end_classification bit */ continue; } uint8_t is_compatible = class_compatibility[pd_class_num][pse_class_num]; /* if compatible class, read requested power info */ if(!is_compatible) { /* sw disable port (unless auto pin is high) */ LTC4296_writeRegister(0x13+0x10*port, 2 | (1<<14)); continue; // next port } pncfg0_old |= (3<<5) | 1 | (1<<13); /* make sure sw_pwr_avail and pse_ready is set */ LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old); LTC4296_writeRegister(REG_P0CFG0 + 0x10*port, pncfg0_old | (1<<14)); /* end_classification */ /* wait for pse_status == 2 or 1 */ pse_status = LTC4296_pseStatus(port); t0 = HAL_GetTick(); while(pse_status != PSE_STATUS_DELIVERING && pse_status != PSE_STATUS_SLEEPING) { if(HAL_GetTick() - t0 > 4000) break; pse_status = LTC4296_pseStatus(port); } } } }
Figure 14. Example Implementation of Detection, SCCP, and Port Power-up
SCCP transaction can be evaluated with the EVAL-SPoE-KIT-AZ and the LTC4296-1 GUI. In the drop down menu, boxed in Figure 15, select the maximum PSE class and select Type E. Select classify if classification without power is desired or select power up for classification and subsequent powering up of the PD if it is equal to or less than the maximum PSE class. Once successful power up of the PD has occurred Power Good indicator should light up green as shown in Figure 16.
Refer to EVAL-SPoE-KIT-AZ Evaluation Kit User Guide for EVAL-kit setup.
Figure 15. SCCP Enable Configurations through evaluation GUI
Figure 16. Successful Port Turn On GUI Port Status
Below are detailed descriptions of the SCCP transactions, parts i-vi. With waveforms captured using the setup in Figure 17.
Figure 17. Proceeding Waveform Probe Location
Figure 18. Initialization Sequence
Figure 19. Initialization Sequence Reset Pulse
Figure 20. Initialization Sequence Presence-Detect High Time
Figure 21. Initialization Sequence Presence Detect Low Time
Figure 22. Initialization Sequence Recovery Time
Figure 23. Initialization Sequence PD Reservoir Capacitor Recharge Time
Figure 24. Initialization Sequence Rise Time
Figure 25. Initialization Sequence Fall Time
Figure 26. PSE Writes 0 Time Slot
Figure 27. PSE Writes 1 Time Slot
Figure 28. PSE Broadcast (0xCC)
Figure 29. PSE Read-Scratchpad Command (0xAA)
Bit(s) | Name | Description | |
---|---|---|---|
b[15:8] | Reserved | Value Always 0 | Read Only |
b[7:0] | Voltage at PD PI during presence pulse | ±20mV tolerance, 10mV per LSB | Read Only |
Table 3. Read_VOLT_INFO Command (0xBB)
Bit(s) | Name | Description | |
---|---|---|---|
b[15:12] | Reserved | Value Always 0 | Read Only |
b[11:0] | PPD_req PD requested Power | Power requested by PD, 0.025W per LSB | Read Only |
Table 4. Read_POWER_INFO Command (0x77)
Bit(s) | Name | Description | |
---|---|---|---|
b[15:12] | Reserved | Value Always 0 | Read Only |
b[11:0] | PPD_assign PD Assigned Power | PD assigned power, 0.025W per LSB | Read/Write |
Table 5. Write_POWER_ASSIGN Command (0x99)
Bit(s) | Name | Description | |
---|---|---|---|
b[15:12] | Reserved | Value Always 0 | Read Only |
b[11:0] | PPD_assign PD Assigned Power | PD assigned power, 0.025W per LSB | Read/Write |
Table 6. Read_POWER_ASSIGN Command (0x81)
Figure 30. PSE Read 0 Time Slot
Figure 31. PSE Read 1 Time Slot
Figure 32. Read CLASS_TYPE_INFO low byte
Figure 33. Read CLASS_TYPE_INFO high byte
Figure 34. PD CRC
IEEE 802.3bu defines Class 0-9 and 802.3cg extends these power classes to Class 10-15. The LTC4296-1 is intended to be used in Class 10-15 systems. Table 7 lists the corresponding Class data for CLASS_TYPE_INFO b[9:0].
b[9:0] | Description |
---|---|
0x3FE | Class 0 |
0x3FD | Class 1 |
0x3FB | Class 2 |
0x3F7 | Class 3 |
0x3EF | Class 4 |
0x3DF | Class 5 |
0x3BF | Class 6 |
0x37F | Class 7 |
0x2FF | Class 8 |
0x1FF | Class 9 |
0x001 | Class 10 |
0x002 | Class 11 |
0x003 | Class 12 |
0x004 | Class 13 |
0x005 | Class 14 |
0x006 | Class 15 |
Table 7. CLASS_TYPE_INFO b[9:0] to Corresponding PD Class
Table 8 shows the PSE, PD and cable requirements for Class 10-15.
Class Symbol and Unit | Class Description | Class 10 | Class 11 | Class 12 | Class 13 | Class 14 | Class 15 |
---|---|---|---|---|---|---|---|
VPSE (V) | PSE Output Voltage | 20-30 | 20-30 | 20-30 | 50-58 | 50-58 | 50-58 |
IPI(max) (mA) | Cable Current | 92 | 240 | 632 | 231 | 600 | 1579 |
PClass(min) (W) | PSE Output Power | 1.85 | 4.8 | 12.63 | 11.54 | 30 | 79 |
VPD(min) (V) | PD Input Voltage | 14 | 14 | 14 | 35 | 35 | 35 |
PPD(max) (W) | PD Power | 1.23 | 3.2 | 8.4 | 7.7 | 20 | 52 |
RLINK_SEG_LOOP (Ω) | Cable Resistance | 65 | 25 | 9.5 | 65 | 25 | 9.5 |
Table 8. IEEE 802.3cg Class Power Requirements Matrix for PSE and PDs
IEEE 802.3cg describes Types A-E device types. For 10Base-T1L both PSE and PD must be Type E. Table 9 lists the corresponding Type data for CLASS_TYPE_INFO b[15:12].
b[15:12] | Description |
---|---|
0xE | Type A |
0xD | Type B |
0xB | Type C |
0x7 | Type D |
0xC | Type E |
Table 9. CLASS_TYPE_INFO b[15:12] to Corresponding PD Type