Studer Innotec Xtender Serial Communication C Library  1.5.0
 All Data Structures Files Functions Variables Enumerations Enumerator Macros Pages
scom_port_c99.h
1 /*
2 Copyright (c) 2014 Studer Innotec SA
3 
4 Permission is hereby granted, free of charge, to any person obtaining a copy
5 of this software and associated documentation files (the "Software"), to deal
6 in the Software without restriction, including without limitation the rights
7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 copies of the Software, and to permit persons to whom the Software is
9 furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 THE SOFTWARE.
21 */
22 
23 /*
24  * This file implements the needed porting functions and macros on a C99 compiler. It as been tested
25  * with gcc on x86 (32 bit, little endian).
26  * The float conversion functions are not totally portable.
27  */
28 
29 #ifndef SCOM_PORT_C99_H
30 
31 
32 #define SCOM_PORT_C99_H
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 /* for size_t and NULL */
39 #include <stddef.h>
40 
41 /* for uint16_t, uint32_t, etc. */
42 #include <stdint.h>
43 
44 
45 /* ----- write and read access to raw buffer data ---------------
46  * These functions allow the read and write in a portable way
47  * independent of the processor byte order in a buffer.
48  * "le" stands for little endian, i.e. LSB byte first.
49  * They should be portable, were tested on little endian platform and should
50  * also work on big or mixed endian platforms.
51  * Float conversion functions are not portable but they are only
52  * used in the examples.
53  */
54 
55 static inline void scom_write_le32(char *const p, const uint32_t data)
56 {
57  *(p) = (data) & 0xFF;
58  *(p+1) = (data >> 8) & 0xFF;
59  *(p+2) = (data >> 16) & 0xFF;
60  *(p+3) = (data >> 24) & 0xFF;
61 }
62 
63 
64 static inline uint32_t scom_read_le32(const char *const p)
65 {
66  return ((*p) & 0xFF) | ((*(p+1) & 0xFF) << 8) |
67  ((*(p+2) & 0xFF)<< 16) | ((*(p+3) & 0xFF) << 24) ;
68 }
69 
70 
71 static inline void scom_write_le16(char *const p, const uint16_t data)
72 {
73  *(p) = (data) & 0xFF;
74  *(p+1) = (data >> 8) & 0xFF;
75 }
76 
77 
78 static inline uint16_t scom_read_le16(const char *const p)
79 {
80  return ((*(p)) & 0xFF) | ((*(p+1) & 0xFF) << 8) ;
81 }
82 
83 
84 static inline float scom_read_le_float(const char *const p)
85 {
86  /* this way of doing it is not portable.
87  The union may not be aligned correctly.
88  The float type on the architecture may not be IEEE754. */
89  union {
90  float floating;
91  uint32_t integer;
92  } val;
93 
94  /* use the endian independent function */
95  val.integer = scom_read_le32(p);
96 
97  return val.floating;
98 }
99 
100 
101 static inline void scom_write_le_float(char *const p, float data)
102 {
103  /* this way of doing it is not portable.
104  The union may not be aligned correctly.
105  The float type on the architecture may not be IEEE754. */
106  union {
107  float floating;
108  uint32_t integer;
109  } val;
110 
111  val.floating = data;
112 
113  /* use the endian independent function */
114  scom_write_le32(p, val.integer);
115 
116 }
117 
118 #ifdef __cplusplus
119 }
120 #endif
121 
122 #endif