Imports pisocanfd_net

Public Class Form1
    Enum CANPORT
        CAN1 = 1
        CAN2
    End Enum

    Dim SelectedCardOpen As Boolean = False
    Dim SelectedBoardNo As Byte = 0
    Dim SelectedCardPortNo As Byte = 0

    'Data Length Code to Number of CAN data bytes 
    Dim CANFD_DLC2DBN() As Byte = New Byte(15) {0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64}



    Private Sub btnScan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnScan.Click
        Dim iRet As UInteger = 0
        Dim i As Byte = 0, BoardID As Byte = 0

        cboModuleName.Items.Clear()
        For i = 0 To 16
            Dim str As String

            iRet = PISOCANFD.CANFD_GetCardBoardID(i, BoardID)
            If iRet = 0 Then
                Select Case BoardID
                    Case 1 'PISO-CAN200U-FD
                        str = String.Format("BoardNo: {0:D2}, {1}", i, "PISO-CAN200U-FD")
                    Case 2 'PISO-CAN400U-FD
                        str = String.Format("BoardNo: {0:D2}, {1}", i, "PISO-CAN400U-FD")
                    Case 3 'PEX-CAN200i-FD
                        str = String.Format("BoardNo: {0:D2}, {1}", i, "PEX-CAN200i-FD")
                    Case 4 'PCM-CAN200-FD
                        str = String.Format("BoardNo: {0:D2}, {1}", i, "PCM-CAN200-FD")
                    Case Else
                        str = String.Format("BoardNo: {0:D2}, Not Support(0x{1:X})", i, BoardID)
                End Select
            Else
                str = String.Format("BoardNo: {0:D2}, {1}", i, "NONE")
            End If

            cboModuleName.Items.Add(str)
        Next i

        cboModuleName.SelectedIndex = 0

    End Sub

    Private Sub cboModuleName_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboModuleName.SelectedIndexChanged
        [SelectedBoardNo] = Convert.ToUInt16(cboModuleName.SelectedIndex)

        Dim iRet As UInteger = 0
        Dim PortNum As Byte = 0

        If (cboModuleName.Text.Length > 20) Then
            iRet = PISOCANFD.CANFD_GetCardPortNum(SelectedBoardNo, PortNum)
            If iRet = 0 Then
                Select Case PortNum
                    Case 2
                        SelectedCardPortNo = PortNum
                    Case 4
                        SelectedCardPortNo = PortNum
                    Case Else
                        SelectedCardPortNo = 0
                End Select
            End If
            btnActive.Enabled = True

        Else
            SelectedCardPortNo = 0
            btnActive.Enabled = False
        End If

    End Sub

    Private Sub btnOpen_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnActive.Click
        Dim iRet As Integer = 0
        Dim BoardNo As Byte
        Dim message As String
        Dim caption As String

        BoardNo = SelectedBoardNo

        If (SelectedCardOpen = True) Then

            tmrRxMsg.Enabled = False

            'Close Device
            iRet = PISOCANFD.CANFD_CloseBoard(SelectedBoardNo)
            If (iRet <> 0) Then
                message = String.Format("Fail to close devboardice.[CANFD_CloseBoard, iRet=0x{0:X}]", iRet)
                caption = "Error"
                MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
            Else
                SelectedCardOpen = False

                btnScan.Enabled = True
                cboModuleName.Enabled = True
                btnActive.Text = "Active"

                grpSendMessage.Enabled = False
                grpReceiveMessage.Enabled = False
            End If
        Else

            Dim SetDeviceParam As Boolean = True
            Dim OPMode, ISOMode As Byte
            Dim BR_Arbit, BR_DataPhase As UInteger
            Dim BR_ArbitSP, BR_DataPhaseSP As UShort

            'Active(Board)
            iRet = PISOCANFD.CANFD_ActiveBoard(BoardNo)
            If (iRet = 0) Then
                '====== Set CAN P1 parameters ======
                'Initialize CAN P1
                If (SetDeviceParam = True) Then
                    iRet = PISOCANFD.CANFD_Init(BoardNo, CANPORT.CAN1)
                    If (iRet <> 0) Then
                        message = String.Format("Initialize CAN Port1 error. [CANFD_Init, iRet=0x{0:X}].", iRet)
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                'Set CAN P1 baudrate and sample point                    
                If (SetDeviceParam = True) Then
                    BR_Arbit = Convert.ToUInt32(Convert.ToSingle(txtABaudrate.Text) * 1000.0)
                    BR_DataPhase = Convert.ToUInt32(Convert.ToSingle(txtDBaudrate.Text) * 1000.0)
                    BR_ArbitSP = Convert.ToUInt16(Convert.ToSingle(txtASamplePoint.Text) * 100.0)
                    BR_DataPhaseSP = Convert.ToUInt16(Convert.ToSingle(txtDSamplePoint.Text) * 100.0)
                    If ((BR_Arbit > 5000 And BR_Arbit <= 2000000) And (BR_DataPhase > 100000 And BR_DataPhase <= 5000000) And _
                        (BR_ArbitSP > 0 And BR_ArbitSP <= 10000) And (BR_DataPhaseSP > 0 And BR_DataPhaseSP <= 10000)) Then

                        iRet = PISOCANFD.CANFD_SetBitRateWithSP(BoardNo, CANPORT.CAN1, BR_Arbit, BR_DataPhase, BR_ArbitSP, BR_DataPhaseSP)
                        If (iRet <> 0) Then
                            message = String.Format("Set CAN Port1 baudrate and sample point error. [CANFD_SetCANADBaudRate, iRet=0x{0:X}].", iRet)
                            caption = "Error"
                            MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                            SetDeviceParam = False
                        End If
                    Else
                        message = String.Format("Port1 baudrate or sample point parameters error.")
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                'Set CAN P1 Port ISO mode
                If (SetDeviceParam = True) Then
                    'Set CAN Port to use ISO-11898 CAN FD specification
                    ISOMode = 1 '1: ISO-11898, 0:  Bosch v1.0

                    iRet = PISOCANFD.CANFD_SetISOCRCEn(BoardNo, CANPORT.CAN1, ISOMode)
                    If (iRet <> 0) Then
                        message = String.Format("Set CAN Port1 ISO mode error. [CANFD_SetISOCRCEn, iRet=0x{0:X}].", iRet)
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                'Set CAN P1 Port Operation mode
                If (SetDeviceParam = True) Then
                    'Set CAN Port to CAN FD Mode
                    OPMode = 0 '0: CAN FD, 1: CAN 2.0, 2: Listen Only

                    iRet = PISOCANFD.CANFD_SetOPMode(BoardNo, CANPORT.CAN1, OPMode)
                    If (iRet <> 0) Then
                        message = String.Format("Set CAN Port1 operation mode error. [CANFD_SetOPMode, iRet=0x{0:X}].", iRet)
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                '====== Emd of Set CAN P1 parameters ======

                '====== Set CAN P2 parameters ======
                'Initialize CAN P2
                If (SetDeviceParam = True) Then
                    iRet = PISOCANFD.CANFD_Init(BoardNo, CANPORT.CAN2)
                    If (iRet <> 0) Then
                        message = String.Format("Initialize CAN Port2 error. [CANFD_Init, iRet=0x{0:X}].", iRet)
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                'Set CAN P2 baudrate and sample point                    
                If (SetDeviceParam = True) Then
                    BR_Arbit = Convert.ToUInt32(Convert.ToSingle(txtABaudrate.Text) * 1000.0)
                    BR_DataPhase = Convert.ToUInt32(Convert.ToSingle(txtDBaudrate.Text) * 1000.0)
                    BR_ArbitSP = Convert.ToUInt16(Convert.ToSingle(txtASamplePoint.Text) * 100.0)
                    BR_DataPhaseSP = Convert.ToUInt16(Convert.ToSingle(txtDSamplePoint.Text) * 100.0)
                    If ((BR_Arbit > 5000 And BR_Arbit <= 2000000) And (BR_DataPhase > 100000 And BR_DataPhase <= 5000000) And _
                        (BR_ArbitSP > 0 And BR_ArbitSP <= 10000) And (BR_DataPhaseSP > 0 And BR_DataPhaseSP <= 10000)) Then

                        iRet = PISOCANFD.CANFD_SetBitRateWithSP(BoardNo, CANPORT.CAN2, BR_Arbit, BR_DataPhase, BR_ArbitSP, BR_DataPhaseSP)
                        If (iRet <> 0) Then
                            message = String.Format("Set CAN Port2 baudrate and sample point error. [CANFD_SetCANADBaudRate, iRet=0x{0:X}].", iRet)
                            caption = "Error"
                            MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                            SetDeviceParam = False
                        End If
                    Else
                        message = String.Format("Port2 baudrate or sample point parameters error.")
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                'Set CAN P2 Port ISO mode
                If (SetDeviceParam = True) Then
                    'Set CAN Port to use ISO-11898 CAN FD specification
                    ISOMode = 1 '1: ISO-11898, 0:  Bosch v1.0

                    iRet = PISOCANFD.CANFD_SetISOCRCEn(BoardNo, CANPORT.CAN2, ISOMode)
                    If (iRet <> 0) Then
                        message = String.Format("Set CAN Port2 ISO mode error. [CANFD_SetISOCRCEn, iRet=0x{0:X}].", iRet)
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                'Set CAN P2 Port Operation mode
                If (SetDeviceParam = True) Then
                    'Set CAN Port to CAN FD Mode
                    OPMode = 0 '0: CAN FD, 1: CAN 2.0, 2: Listen Only

                    iRet = PISOCANFD.CANFD_SetOPMode(BoardNo, CANPORT.CAN2, OPMode)
                    If (iRet <> 0) Then
                        message = String.Format("Set CAN Port2 operation mode error. [CANFD_SetOPMode, iRet=0x{0:X}].", iRet)
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If

                '====== Emd of Set CAN P2 parameters ======

                'Install CAN Rx IRQ
                If (SetDeviceParam = True) Then
                    iRet = PISOCANFD.CANFD_InstallIrq(BoardNo)
                    If (iRet <> 0) Then
                        message = String.Format("Set Board {0}, IRQ error. [CANFD_InstallIrq, iRet=0x{2:X}].", BoardNo, iRet)
                        caption = "Error"
                        MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
                        SetDeviceParam = False
                    End If
                End If


                If (SetDeviceParam = True) Then
                    SelectedCardOpen = True

                    btnScan.Enabled = False
                    cboModuleName.Enabled = False
                    btnActive.Text = "Close"

                    grpSendMessage.Enabled = True
                    grpReceiveMessage.Enabled = True

                    cboSendMsg_Mode.SelectedIndex = 0
                    cboSendMsg_Type.SelectedIndex = 0
                    cboSendMsg_DLC.SelectedIndex = 8
                    cboSendMsg_Port.SelectedIndex = 0
                    lstReceiveMessage.Items.Clear()

                    tmrRxMsg.Enabled = True
                Else
                    PISOCANFD.CANFD_CloseBoard(SelectedBoardNo)

                End If
            Else
                message = String.Format("Fail to active board.[CANFD_ActiveBoard, iRet=0x{0:X}]", iRet)
                caption = "Error"
                MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End If
    End Sub

    Private Sub txtSendMsg_D1_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtSendMsg_Data.KeyPress
        'this will only allow valid hex values [0-9][a-f][A-F] to be entered. See ASCII table
        Dim c As Char = e.KeyChar
        If c <> Chr(8) And Not ((c <= "f" And c >= "a") Or (c <= "F" And c >= "A") Or (c >= "0" And c <= "9") Or (c = Chr(44)) Or (c = "-")) Then
            e.Handled = True
        End If
    End Sub

    Private Sub txtSendMsg_ID_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtSendMsg_ID.KeyPress
        'this will only allow valid hex values [0-9][a-f][A-F] to be entered. See ASCII table
        Dim c As Char = e.KeyChar
        If c <> Chr(8) And Not ((c <= "f" And c >= "a") Or (c <= "F" And c >= "A") Or (c >= "0" And c <= "9") Or (c = Chr(44))) Then
            e.Handled = True
        End If
    End Sub

    Private Sub txtSendMsg_ID_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSendMsg_ID.TextChanged
        If (txtSendMsg_ID.Text <> "") Then
            Dim value As UInteger = Convert.ToUInt32(txtSendMsg_ID.Text, 16)
            If (cboSendMsg_Mode.SelectedIndex = 0) Then ''2.0A ID
                If (value > &H7FF) Then
                    txtSendMsg_ID.Text = "7FF"
                End If
            Else
                If (value > &H1FFFFFFF) Then
                    txtSendMsg_ID.Text = "1FFFFFFF"
                End If
            End If
        End If

        txtSendMsg_ID.Text = txtSendMsg_ID.Text.ToUpper()
        txtSendMsg_ID.SelectionStart = txtSendMsg_ID.Text.Length
    End Sub

    Private Sub txtSendMsg_ID_Leave(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSendMsg_ID.Leave
        If (cboSendMsg_Mode.SelectedIndex = 0) Then '2.0A ID
            txtSendMsg_ID.Text = txtSendMsg_ID.Text.PadLeft(3, "0")
        Else
            txtSendMsg_ID.Text = txtSendMsg_ID.Text.PadLeft(8, "0")
        End If

    End Sub

    Private Sub cboSendMsg_Type_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboSendMsg_Type.SelectedIndexChanged
        cboSendMsg_DLC.Items.Clear()

        If (cboSendMsg_Type.SelectedIndex = 0 Or cboSendMsg_Type.SelectedIndex = 1) Then 'Normal CAN
            cboSendMsg_DLC.Items.Add("0")
            cboSendMsg_DLC.Items.Add("1")
            cboSendMsg_DLC.Items.Add("2")
            cboSendMsg_DLC.Items.Add("3")
            cboSendMsg_DLC.Items.Add("4")
            cboSendMsg_DLC.Items.Add("5")
            cboSendMsg_DLC.Items.Add("6")
            cboSendMsg_DLC.Items.Add("7")
            cboSendMsg_DLC.Items.Add("8")
        Else 'CAN FD
            cboSendMsg_DLC.Items.Add("0")
            cboSendMsg_DLC.Items.Add("1")
            cboSendMsg_DLC.Items.Add("2")
            cboSendMsg_DLC.Items.Add("3")
            cboSendMsg_DLC.Items.Add("4")
            cboSendMsg_DLC.Items.Add("5")
            cboSendMsg_DLC.Items.Add("6")
            cboSendMsg_DLC.Items.Add("7")
            cboSendMsg_DLC.Items.Add("8")
            cboSendMsg_DLC.Items.Add("12")
            cboSendMsg_DLC.Items.Add("16")
            cboSendMsg_DLC.Items.Add("20")
            cboSendMsg_DLC.Items.Add("24")
            cboSendMsg_DLC.Items.Add("32")
            cboSendMsg_DLC.Items.Add("48")
            cboSendMsg_DLC.Items.Add("64")
        End If

        cboSendMsg_DLC.SelectedIndex = 8
    End Sub

    Private Sub cboSendMsg_Mode_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboSendMsg_Mode.SelectedIndexChanged
        Dim value As UInteger = Convert.ToUInt32(txtSendMsg_ID.Text, 16)
        If (cboSendMsg_Mode.SelectedIndex = 0) Then '2.0A ID
            txtSendMsg_ID.MaxLength = 3
            txtSendMsg_ID.Text = Convert.ToString(value, 16).PadLeft(3, "0")
        Else '2.0B ID
            txtSendMsg_ID.MaxLength = 8
            txtSendMsg_ID.Text = Convert.ToString(value, 16).PadLeft(8, "0")
        End If
    End Sub

    Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
        Dim iRet As Integer

        Dim MODE As Byte
        Dim ID As UInteger
        Dim TYPE As Byte
        Dim DLC As Byte
        Dim DATA As Byte() = New Byte(63) {}
        Dim message As String
        Dim caption As String

        MODE = cboSendMsg_Mode.SelectedIndex
        ID = Convert.ToUInt32(txtSendMsg_ID.Text, 16)
        TYPE = cboSendMsg_Type.SelectedIndex
        DLC = cboSendMsg_DLC.SelectedIndex

        'convert data string to byte array
        Dim hexValues As String = txtSendMsg_Data.Text
        Dim hexValuesSplit As String() = hexValues.Split("-")
        Dim hexValuesLen As Integer

        If hexValuesSplit.Length > 64 Then
            hexValuesLen = 64
        Else
            hexValuesLen = hexValuesSplit.Length
        End If

        For i As Integer = 0 To hexValuesLen - 1
            DATA(i) = Convert.ToByte(hexValuesSplit(i), 16)
        Next i


        If (cboSendMsg_Port.SelectedIndex = 0) Then  'CAN1
            iRet = PISOCANFD.CANFD_SendCANMsg(SelectedBoardNo, CANPORT.CAN1, MODE, ID, TYPE, DLC, DATA)
            If (iRet <> 0) Then
                message = String.Format("Send CAN1 Message error. [CANFD_SendCANMsg, iRet=0x{0:X}].", iRet)
                caption = "Error"
                MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If

        Else 'CAN2
            iRet = PISOCANFD.CANFD_SendCANMsg(SelectedBoardNo, CANPORT.CAN2, MODE, ID, TYPE, DLC, DATA)
            If (iRet <> 0) Then
                message = String.Format("Send CAN2 Message error. [CANFD_SendCANMsg, iRet=0x{0:X}].", iRet)
                caption = "Error"
                MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error)
            End If
        End If
    End Sub

    Private Sub tmrRxMsg_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrRxMsg.Tick
        Dim iRet As Integer
        Dim DataCount As UInteger
        'CAN Information
        Dim CAN_ID As UInteger = 0
        Dim CAN_Mode As Byte = 0
        Dim CAN_Type As Byte = 0
        Dim CAN_Dlen As Byte = 0
        Dim CAN_Data As Byte() = New Byte(63) {}
        Dim CAN_HTime As UInteger = 0
        Dim CAN_LTime As UInteger = 0
        Dim message As String
        Dim u64Data As UInt64

        If (SelectedCardOpen = True) Then
            'Receive CAN1 Message
            iRet = PISOCANFD.CANFD_RecvCANMsgCnt(SelectedBoardNo, CANPORT.CAN1, DataCount)
            If (iRet = 0 And DataCount > 0) Then
                iRet = PISOCANFD.CANFD_RecvCANMsg(SelectedBoardNo, CANPORT.CAN1, CAN_Mode, CAN_ID, CAN_Type, CAN_Dlen, CAN_Data, CAN_HTime, CAN_LTime)
                If (iRet = 0) Then
                    u64Data = ((CAN_HTime << 32) + CAN_LTime)
                    CAN_Dlen = CANFD_DLC2DBN(CAN_Dlen)

                    If (CAN_Mode = 0) Then    '2.0A
                        message = String.Format("CAN1: [{0}] Mode={1}, ID={2:X3}, Type={3}, DLC={4}, ", (u64Data / 10000000), CAN_Mode, CAN_ID, CAN_Type, CAN_Dlen)
                    Else
                        message = String.Format("CAN1: [{0}] Mode={1}, ID={2:X8}, Type={3}, DLC={4} ", (u64Data / 10000000), CAN_Mode, CAN_ID, CAN_Type, CAN_Dlen)
                    End If

                    If (CAN_TYPE = 0) Then 'No RTR frame
                        If (CAN_Dlen > 0) Then
                            message = message + String.Format("DATA=")
                        End If

                        For i As Byte = 1 To CAN_Dlen
                            message = message + String.Format("{0:X2} ", CAN_Data(i - 1))
                        Next
                    End If

                    lstReceiveMessage.Items.Add(message)

                End If
            End If

            'Receive CAN2 Message
            iRet = PISOCANFD.CANFD_RecvCANMsgCnt(SelectedBoardNo, CANPORT.CAN2, DataCount)
            If (iRet = 0 And DataCount > 0) Then
                iRet = PISOCANFD.CANFD_RecvCANMsg(SelectedBoardNo, CANPORT.CAN2, CAN_Mode, CAN_ID, CAN_Type, CAN_Dlen, CAN_Data, CAN_HTime, CAN_LTime)
                If (iRet = 0) Then
                    u64Data = ((CAN_HTime << 32) + CAN_LTime)
                    CAN_Dlen = CANFD_DLC2DBN(CAN_Dlen)

                    If (CAN_Mode = 0) Then    '2.0A
                        message = String.Format("CAN2: [{0}] Mode={1}, ID={2:X3}, Type={3}, DLC={4}, ", (u64Data / 10000000), CAN_Mode, CAN_ID, CAN_Type, CAN_Dlen)
                    Else
                        message = String.Format("CAN2: [{0}] Mode={1}, ID={2:X8}, Type={3}, DLC={4} ", (u64Data / 10000000), CAN_Mode, CAN_ID, CAN_Type, CAN_Dlen)
                    End If

                    If (CAN_Type <> 0) Then 'Not Remote frame
                        If (CAN_Dlen > 0) Then
                            message = message + String.Format("DATA=")
                        End If

                        For i As Byte = 1 To CAN_Dlen
                            message = message + String.Format("{0:X2} ", CAN_Data(i - 1))
                        Next
                    End If

                    lstReceiveMessage.Items.Add(message)

                End If
            End If

            lstReceiveMessage.SelectedIndex = lstReceiveMessage.Items.Count - 1
        End If

    End Sub

    Private Sub btnClear_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClear.Click
        lstReceiveMessage.Items.Clear()
    End Sub


End Class
