
' Below code is created by  chun@icpdas.com  on Nov.28,2006

Option Explicit On   ' Each variable must be declared well

Imports System
Imports System.Runtime.InteropServices


' VB.net 2005 format
' -------------------------------------------------------------------------------------
' Single  :  4 bytes : -3.4028235E+38 through -1.401298E-45 for negative values 
'                       1.401298E-45 through 3.4028235E+38 for positive values
' Int32   :  4 bytes : -2,147,483,648 through 2,147,483,647 (signed) 
' UInt32  :  4 bytes : 0 through 4,294,967,295 (unsigned)
' Int16   :  2 bytes : 32,768 through 32,767 (signed)
' UInt16  :  2 bytes : 0 through 65,535 (unsigned)
' SByte   :  1 byte  : -128 through 127 (signed)
' Byte    :  1 byte  : 0 through 255 (unsigned)
' Boolean :          : True or False
' -------------------------------------------------------------------------------------


' vMap function or sub, Must using in INTEL format CPU
' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
' vMap.Int32_to_Mbus_four_Byte( ) : Map Int32 value to become four Byte values in Modbus format
' vMap.Mbus_four_Byte_to_Int32( ) : Map four Byte values in Modbus format to become Int32 value 

' vMap.Single_to_Mbus_four_Byte( ) : Map 32-bit Single floating point value to become four Byte values in Modbus format
' vMap.Mbus_four_Byte_to_Single( ) : Map four Byte values in Modbus format to become 32-bit Single floating point value 

' vMap.Int16_to_Mbus_two_Byte( ) : Map Int16 value to become two Byte value in Modbus format
' vMap.Mbus_two_Byte_to_Int16( ) : Map two Byte value in Modbus format to become Int16 value 

' vMap.Byte_to_Mbus_eight_Boolean( ) :  Map Byte value to eight Boolean values in Modbus format
' vMap.Mbus_eight_Boolean_to_Byte( ) :  Map eight Boolean values in Modbus format to Byte value 

' vMap.Int32_to_Single( )       :  Map Int32 value to become a 32-bit Single floating point value
' vMap.Single_to_Int32( )       :  Map 32-bit Single floating point value to become a Int32 value

' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Module vMap

    Dim Ptr1 As IntPtr = Marshal.AllocHGlobal(16)   ' allocate 16 bytes to Ptr1


    ' Map Int32 value to become four Byte values in Modbus format
    ' Parameter:
    '   Int32_val:  Int32 value to be convertered
    '   Byte1 ~ 4:  Byte1 to 4 in Modbus protocol order to store the result (LoWord Hi, LoWord Lo, HiWord Hi, HiWord Lo)
    Public Sub Int32_to_Mbus_four_Byte(ByVal Int32_val As Int32, ByRef Byte1 As Byte, ByRef Byte2 As Byte, _
                                  ByRef Byte3 As Byte, ByRef Byte4 As Byte)

        Dim V(2) As Int32
        Dim B(8) As Byte

        V(0) = Int32_val
        Marshal.Copy(V, 0, Ptr1, 1)   ' copy V(0) 's 4 bytes to Ptr1
        Marshal.Copy(Ptr1, B, 0, 4)   ' copy Ptr1's 4 byte to B(0) ~ (3)

        ' store the result
        Byte1 = B(1)       ' LoWord Hi 
        Byte2 = B(0)       ' LoWord Lo 
        Byte3 = B(3)       ' HiWord Hi 
        Byte4 = B(2)       ' HiWord Lo 

    End Sub


    ' Map four Byte values in Modbus format to become Int32 value  
    ' Parameter:    
    '   Byte1 ~ 4:  Byte1 to 4 in Modbus protocol order to be converted (LoWord Hi, LoWord Lo, HiWord Hi, HiWord Lo)
    '   Int32_val:  Int32 value-pointer which will store the result 
    Public Sub Mbus_four_Byte_to_Int32(ByVal Byte1 As Byte, ByVal Byte2 As Byte, ByVal Byte3 As Byte, _
                                  ByVal Byte4 As Byte, ByRef Int32_val As Int32)

        Dim V(2) As Int32
        Dim B(8) As Byte

        B(0) = Byte2     ' Lowest byte
        B(1) = Byte1
        B(2) = Byte4
        B(3) = Byte3     ' Highest

        Marshal.Copy(B, 0, Ptr1, 4)   ' copy B1(0) ~ (3) 's 4 bytes to Ptr1
        Marshal.Copy(Ptr1, V, 0, 1)   ' copy Ptr1's 4 byte to V(0)

        ' store the result
        Int32_val = V(0)

    End Sub


    ' Map 32-bit Single floating point value to become four Byte values in Modbus format
    ' Parameter:
    '   Single_val:  32-bit Single floating point value to be convertered
    '   Byte1 ~ 4:   Byte1 to 4 in Modbus protocol order to store the result (LoWord Hi, LoWord Lo, HiWord Hi, HiWord Lo)
    '   True:  succeed !  
    '   False: Failed.  
    Public Function Single_to_Mbus_four_Byte(ByVal Single_val As Single, ByRef Byte1 As Byte, ByRef Byte2 As Byte, _
                                  ByRef Byte3 As Byte, ByRef Byte4 As Byte) As Boolean

        Dim F(2) As Single
        Dim B(8) As Byte
        Dim ret As Boolean = True

        If Single.IsNaN(Single_val) = True Then  ' not a single value
            ret = False
        Else
            F(0) = Single_val
        End If

        If ret = True Then
            Try
                Marshal.Copy(F, 0, Ptr1, 1)   ' copy F(0) 's 4 bytes to Ptr1
                Marshal.Copy(Ptr1, B, 0, 4)   ' copy Ptr1's 4 byte to B(0) ~ (3)
            Catch ex As Exception
                ret = False
            End Try
        End If

        ' store the result
        If ret = True Then
            Byte1 = B(1)       ' LoWord Hi 
            Byte2 = B(0)       ' LoWord Lo 
            Byte3 = B(3)       ' HiWord Hi 
            Byte4 = B(2)       ' HiWord Lo 
        End If

        Return ret

    End Function


    ' Map four Byte values in Modbus format to become 32-bit Single floating point value  
    ' Parameter:    
    '   Byte1 ~ 4:  Byte1 to 4 in Modbus protocol order to be converted (LoWord Hi, LoWord Lo, HiWord Hi, HiWord Lo)
    '   Single_val:  32-bit Single floating point value-pointer which will store the result 
    '   True:  succeed !  
    '   False: Failed.  
    Public Function Mbus_four_Byte_to_Single(ByVal Byte1 As Byte, ByVal Byte2 As Byte, ByVal Byte3 As Byte, _
                                  ByVal Byte4 As Byte, ByRef Single_val As Single) As Boolean

        Dim F(2) As Single
        Dim B(8) As Byte
        Dim ret As Boolean = True

        B(0) = Byte2     ' Lowest byte
        B(1) = Byte1
        B(2) = Byte4
        B(3) = Byte3     ' Highest

        Try
            Marshal.Copy(B, 0, Ptr1, 4)   ' copy B1(0) ~ (3) 's 4 bytes to Ptr1
            Marshal.Copy(Ptr1, F, 0, 1)   ' copy Ptr1's 4 byte to F(0)
        Catch ex As Exception
            ret = False
        End Try

        ' store the result
        If Single.IsNaN(F(0)) = True Then
            ret = False
        End If

        If ret = True Then
            Single_val = F(0)
        End If

        Return ret

    End Function



    ' Map Int16 value to become two Byte value in Modbus format
    ' Parameter:
    '   Int16_val:  Int16 value to be convertered
    '   Byte1 ~ 2:  Byte1 to 2 in Modbus protocol order to store the result (HiByte, LoByte)
    Public Sub Int16_to_Mbus_two_Byte(ByVal Int16_val As Int16, ByRef Byte1 As Byte, ByRef Byte2 As Byte)

        Dim W(2) As Int16
        Dim B(8) As Byte

        W(0) = Int16_val
        Marshal.Copy(W, 0, Ptr1, 1)   ' copy W(0) 's 2 bytes to Ptr1
        Marshal.Copy(Ptr1, B, 0, 2)   ' copy Ptr1's 2 byte to B(0) ~ (1)

        ' store the result
        Byte1 = B(1)       ' HiByte 
        Byte2 = B(0)       ' LoByte 

    End Sub


    ' Map two Byte value in Modbus format to become Int16 value  
    ' Parameter:    
    '   Byte1 ~ 2:  Byte1 to 2 in Modbus protocol order to be converted (LoByte, HiByte)
    '   Int16_val:  Int16 value-pointer which will store the result 
    Public Sub Mbus_two_Byte_to_Int16(ByVal Byte1 As Byte, ByVal Byte2 As Byte, ByRef Int16_val As Int16)

        Dim W(2) As Int16
        Dim B(8) As Byte

        B(0) = Byte2     ' Lowest byte
        B(1) = Byte1

        Marshal.Copy(B, 0, Ptr1, 2)   ' copy B1(0) ~ (1) 's 2 bytes to Ptr1
        Marshal.Copy(Ptr1, W, 0, 1)   ' copy Ptr1's 2 byte to W(0)

        ' store the result
        Int16_val = W(0)

    End Sub



    ' Map Int32 value to become a 32-bit Single floating point value
    ' Parameter:
    '   Int32_val:  The int32 value to be convertered
    '   Float_val:  32-bit floating point value-pointer which will store the result 
    ' Return:
    '   True:  succeed !  Then the Single_val can be used by user
    '   False: Failed.  Can not map, the Single_val can not be used.
    Public Function Int32_to_Single(ByVal Int32_val As Int32, ByRef Single_val As Single) As Boolean

        Dim V(2) As Int32
        Dim F(2) As Single
        Dim ret As Boolean = True

        V(0) = Int32_val

        Try
            Marshal.Copy(V, 0, Ptr1, 1)   ' copy V(0) 's 4 bytes to Ptr1
            Marshal.Copy(Ptr1, F, 0, 1)   ' copy Ptr1's 4 byte to F(0)
        Catch ex As Exception
            ' exception happens
            ret = False
        End Try

        ' check vale
        If Single.IsNaN(F(0)) = True Then  ' not a single value
            ret = False
        End If

        If ret = True Then
            Single_val = F(0)
        End If

        Return ret

    End Function


    ' Map 32-bit Single floating point value to become a Int32 value
    ' Parameter:
    '   Single_val:  32-bit floating point value to be convertered
    '   Int32_val:  The int32 value-pointer which will store the result 
    ' Return:
    '   True:  succeed !  Then the Int32_val can be used by user
    '   False: Failed.  Can not map, the Int32_val can not be used.
    Public Function Single_to_Int32(ByVal Single_val As Single, ByRef Int32_val As Int32) As Boolean

        Dim V(2) As Int32
        Dim F(2) As Single
        Dim ret As Boolean = True

        If Single.IsNaN(Single_val) = True Then  ' check if it is a value
            ret = False
        Else
            F(0) = Single_val
        End If

        If ret = True Then
            Try
                Marshal.Copy(F, 0, Ptr1, 1)   ' copy F(0) 's 4 bytes to Ptr1
                Marshal.Copy(Ptr1, V, 0, 1)   ' copy Ptr1's 4 byte to V(0)
            Catch ex As Exception
                ' exception happens
                ret = False
            End Try
        End If

        If ret = True Then
            Int32_val = V(0)
        End If

        Return ret

    End Function


    ' Map Byte value to eight Boolean values in Modbus format  
    ' Parameter:    
    '   Byte_val:   Byte value to be converted (one Byte contains 8 bits)
    '   B1 to B8:   8 Boolean value-pointer which will store the result 
    Public Sub Byte_to_Mbus_eight_Boolean(ByVal Byte_val As Byte, ByRef B1 As Boolean, ByRef B2 As Boolean, _
                                          ByRef B3 As Boolean, ByRef B4 As Boolean, ByRef B5 As Boolean, _
                                          ByRef B6 As Boolean, ByRef B7 As Boolean, ByRef B8 As Boolean)

        Dim ii As Int32
        Dim B(8) As Boolean

        For ii = 0 To 7
            B(ii) = (Byte_val >> ii) And 1
        Next ii

        ' store the result
        B1 = B(0)
        B2 = B(1)
        B3 = B(2)
        B4 = B(3)
        B5 = B(4)
        B6 = B(5)
        B7 = B(6)
        B8 = B(7)

    End Sub


    ' Map eight Boolean values in Modbus format to Byte value  
    ' Parameter:    
    '   B1 to B8 :   8 Boolean value be converted 
    '   Byte_val :   Byte value-pointer which will store the result 
    Public Sub Mbus_eight_Boolean_to_Byte(ByVal B1 As Boolean, ByVal B2 As Boolean, _
                                          ByVal B3 As Boolean, ByVal B4 As Boolean, ByVal B5 As Boolean, _
                                          ByVal B6 As Boolean, ByVal B7 As Boolean, ByVal B8 As Boolean, _
                                          ByRef Byte_val As Byte)

        Byte_val = B1 And 1
        Byte_val = Byte_val Or ((B2 And 1) << 1)
        Byte_val = Byte_val Or ((B3 And 1) << 2)
        Byte_val = Byte_val Or ((B4 And 1) << 3)
        Byte_val = Byte_val Or ((B5 And 1) << 4)
        Byte_val = Byte_val Or ((B6 And 1) << 5)
        Byte_val = Byte_val Or ((B7 And 1) << 6)
        Byte_val = Byte_val Or ((B8 And 1) << 7)

    End Sub


End Module


