/******************************************************************************
* Function Name: Swd_SecondTurnAroundPhase
*******************************************************************************
*
* Summary:
*  Generates one SWDCK clock cycle for Turnaround phase of a SWD packet.
*  SWDIO drive mode is changed to CMOS output drive mode so that the host can
*  write data on SWDIO.
*
* Parameters:
*  None.
*
* Return:
*  None.
*
* Note:
*  This function is called during SWD Read/Write packets
*
******************************************************************************/
static void Swd_SecondTurnAroundPhase(void)
{
	/* Change to CMOS output drive mode for host to write to SWDIO */
    SetSwdioCmosOutput();
    SetSwdckLow();
    SetSwdckHigh();
}
/******************************************************************************
* Function Name: Swd_FirstTurnAroundPhase
*******************************************************************************
*
* Summary:
*  Generates one SWDCK clock cycle for Turnaround phase of a SWD packet.
*  SWDIO drive mode is changed to High-Z drive mode so that the host can read
*  the data on the SWDIO.
*
* Parameters:
*  None.
*
* Return:
*  None.
*
* Note:
*  This function is called during SWD Read/Write packets
*
******************************************************************************/
static void Swd_FirstTurnAroundPhase(void)
{
	/* Change to High-Z drive mode for host to read the SWDIO line */
    SetSwdioHizInput(); 
    SetSwdckLow();
    SetSwdckHigh();
}
/******************************************************************************
* Function Name: Swd_SendByte
*******************************************************************************
*
* Summary:
*  Sends a byte of data on the SWD lines (SWDIO, SWDCK)
*
* Parameters:
*  txByte: Data byte to be sent by host on SWDIO line (Least significant bit
*		   sent first)
*
* Return:
*  None.
*
* Note:
*  This function is called for sending SWD header data in SWD Read/Write
*  packets, and also to send data in a SWD Write packet.
*
******************************************************************************/
static void Swd_SendByte(u8 txByte)
{
    u8 loop = 0;

    /* Loop for 8-bits of a byte */
    for (loop = 0; loop < 8; loop++) {
        if (txByte & LSB_BIT_MASK) {	/* Send a '1' */
            SetSwdckLow();
            SetSwdioHigh();
            SetSwdckHigh();
        } else {	/* Send a '0' */

            SetSwdckLow();
            SetSwdioLow();
            SetSwdckHigh();
        }

        txByte = txByte >> 1;	/* Make the next bit to send as LS bit */
    }
}
/******************************************************************************
* Function Name: Swd_SendDummyClocks
*******************************************************************************
*
* Summary:
*  Sends three SWDCK clock cycles with SWDIO line held low
*
* Parameters:
*  None.
*
* Return:
*  None.
*
* Note:
*  This function is called during SWD Read/Write packets.
*
******************************************************************************/
static void Swd_SendDummyClocks(void)
{
    u8 loop;

    /* Send three SWDCK clock cycles with SWDIO line held low */
    SetSwdioLow();
    for (loop = 0; loop < NUMBER_OF_DUMMY_SWD_CLOCK_CYCLES; loop++) {
        SetSwdckLow();
        SetSwdckHigh();
    }
}
/******************************************************************************
* Function Name: Swd_ReceiveParity
*******************************************************************************
*
* Summary:
*  Receives the 1-bit parity data on SWD lines
*
* Parameters:
*  None.
*
* Return:
*  parity:
*    1-bit parity data returned as a byte (either '1' or '0')
*
* Note:
*  This function is called during SWD Read packet
*
******************************************************************************/
static u8 Swd_ReceiveParity(void)
{
    u8 parity;
    
    /* Make the clock low, Read SWDIO data, Make Clock high */
    
    SetSwdckLow();
    parity = ReadSwdio();
    SetSwdckHigh();    
    
    return(parity);
}
/******************************************************************************
* Function Name: Swd_SendParity
*******************************************************************************
*
* Summary:
*  Sends the 1-bit parity data on SWD lines
*
* Parameters:
*  parity:
*    1-bit parity data received as a byte (either '1' or '0')
*
* Return:
*  None.
*
* Note:
*  This function is called during SWD Write packet
*
******************************************************************************/
static void Swd_SendParity(u8 parity)
{
    /* Make the clock low, Send SWDIO data, Make Clock high */

    SetSwdckLow();
    if (parity) {
        SetSwdioHigh();
    } else {
        SetSwdioLow();
    }
    SetSwdckHigh();
}
/******************************************************************************
* Function Name: Swd_GetAckSegment
********************************************************************************
*
* Summary:
*  Gets the 3-bit ACK response in a SWD packet
*
* Parameters:
*  None.
*
* Return:
*  ack:
*   3-bit ACK response is returned as a byte. Three possible return values are:
*       0x01 - SWD_OK_ACK
*       0x02 - SWD_WAIT_ACK
*       0x04 - SWD_FAULT_ACK
*       Any other return value - Undefined ACK code.
*       Treat it similar to SWD_FAULT_ACK and abort operation.
*
* Note:
*  This function is called during SWD Read/Write packets
*
******************************************************************************/
static u8 Swd_GetAckSegment(void)
{
    u8 ack = 0;
    u8 receiveBit = 0;
    u8 loop = 0;

    /* ACK bits are received lsb bit first */
    for (loop = 0; loop < NUMBER_OF_ACK_BITS; loop++) {
        SetSwdckLow();

        /* Store the ACK bit received */
        receiveBit = ReadSwdio();
        SetSwdckHigh();

        /* Concatenate the ACK bit with ACK data byte */
        ack = ack | (receiveBit << loop);
    }

    return (ack);
}