Merge remote-tracking branch 'origin/master' into tizen
[platform/core/csapi/tizenfx.git] / internals / src / Tizen.Peripheral / Tizen.Peripheral / Spi.cs
1 /*
2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 using System;
18 using NativeSpi = Interop.Peripheral.Spi;
19
20 namespace Tizen.Peripheral.Spi
21 {
22     /// <summary>
23     /// Enumeration of SPI transfer modes.
24     /// </summary>
25     public enum SpiMode
26     {
27         /// <summary>
28         /// CPOL = 0, CPHa = 0 Mode.
29         /// </summary>
30         Mode0 = 0,
31
32         /// <summary>
33         /// CPOL = 0, CPHa = 1 Mode.
34         /// </summary>
35         Mode1,
36
37         /// <summary>
38         /// CPOL = 1, CPHa = 0 Mode.
39         /// </summary>
40         Mode2,
41
42         /// <summary>
43         /// CPOL = 1, CPHa = 1 Mode.
44         /// </summary>
45         Mode3
46     }
47
48     /// <summary>
49     /// Enumeration of bit orders.
50     /// </summary>
51     /// <remarks>
52     /// Currently only LSB order is supported!
53     /// </remarks>
54     public enum BitOrder
55     {
56         /// <summary>
57         /// Use most siginificant bit first.
58         /// </summary>
59         MSB = 0,
60
61         /// <summary>
62         /// Use least siginificant bit first.
63         /// </summary>
64         LSB
65     }
66
67     /// <summary>
68     /// The class allows applications to communicate via SPI platform's bus.
69     /// </summary>
70     /// <privilege>http://tizen.org/privilege/peripheralio</privilege>
71     public class Spi : IDisposable
72     {
73
74         //TODO Provide default values.
75         private SpiMode _transferMode;
76         private BitOrder _bitOrder;
77         private byte _bitsPerWord;
78         private uint _frequency;
79
80         /// <summary>
81         /// Native handle to Spi.
82         /// </summary>
83         private IntPtr _handle;
84         private bool _disposed = false;
85
86         /// <summary>
87         /// Opens a SPI slave device.
88         /// </summary>
89         /// <param name="bus">The SPI bus number.</param>
90         /// <param name="chip">The SPI chip select number.</param>
91         public Spi(int bus, int chip)
92         {
93             var ret = NativeSpi.Open(bus, chip, out IntPtr handle);
94             if (ret != Internals.Errors.ErrorCode.None)
95                 throw ExceptionFactory.CreateException(ret);
96
97             _handle = handle;
98         }
99
100         /// <summary>
101         /// Closes the SPI slave device.
102         /// </summary>
103         ~Spi()
104         {
105             Dispose(false);
106         }
107
108         /// <summary>
109         /// Closes the SPI slave device.
110         /// </summary>
111         public void Close() => Dispose();
112
113         /// <summary>
114         /// Disposes the Spi.
115         /// </summary>
116         public void Dispose()
117         {
118             Dispose(true);
119             GC.SuppressFinalize(this);
120         }
121
122         /// <summary>
123         /// Disposes the Spi.
124         /// </summary>
125         protected virtual void Dispose(bool disposing)
126         {
127             if (_disposed)
128             {
129                 return;
130             }
131
132             NativeSpi.Close(_handle);
133             _disposed = true;
134         }
135
136         /// <summary>
137         /// Reads the bytes data from the SPI slave device.
138         /// </summary>
139         /// <param name="buffer">The Data buffer.</param>
140         public void Read(byte[] buffer)
141         {
142             var length = Convert.ToUInt32(buffer.Length);
143             var ret = NativeSpi.Read(_handle, buffer, length);
144             if (ret != Internals.Errors.ErrorCode.None)
145                 throw ExceptionFactory.CreateException(ret);
146         }
147
148         /// <summary>
149         /// Writes the bytes data to the SPI slave device.
150         /// </summary>
151         /// <param name="data">The data buffer to write.</param>
152         public void Write(byte[] data)
153         {
154             var length = Convert.ToUInt32(data.Length);
155             var ret = NativeSpi.Write(_handle, data, length);
156             if (ret != Internals.Errors.ErrorCode.None)
157                 throw ExceptionFactory.CreateException(ret);
158         }
159
160         /// <summary>
161         /// Exchanges the bytes data to the SPI slave device.
162         /// writeBuffer.Length and readBuffer.Length must be equal.
163         /// </summary>
164         /// <param name="writeBuffer">Array containing data to write to the device.</param>
165         /// <param name="readBuffer">Array containing data read from the dievice.</param>
166         public void TransferSequential(byte[] writeBuffer, byte[] readBuffer)
167         {
168             if (writeBuffer.Length != readBuffer.Length)
169                 throw new Exception("writeBuffer.Length is not equal to readBuffer.Length");
170
171             var buffersLength = Convert.ToUInt32(writeBuffer.Length);
172
173             var ret = NativeSpi.Transfer(_handle, writeBuffer, readBuffer, buffersLength);
174             if (ret != Internals.Errors.ErrorCode.None)
175                 throw ExceptionFactory.CreateException(ret);
176         }
177
178         /// <summary>
179         /// Sets or gets the SPI transfer mode.
180         /// </summary>
181         /// <remarks>Get value is initialized after successful Set call.</remarks>
182         public SpiMode Mode
183         {
184             get => _transferMode;
185             set
186             {
187                 var ret = NativeSpi.SetMode(_handle, (NativeSpi.Mode)value);
188                 if (ret != Internals.Errors.ErrorCode.None)
189                     throw ExceptionFactory.CreateException(ret);
190
191                 _transferMode = value;
192             }
193         }
194
195         /// <summary>
196         /// Sets or gets the SPI bit order.
197         /// </summary>
198         /// <remarks>Get value is initialized after successful Set call.</remarks>
199         public BitOrder BitOrder
200         {
201             get => _bitOrder;
202             set
203             {
204                 var ret = NativeSpi.SetBitOrder(_handle, (NativeSpi.BitOrder)value);
205                 if (ret != Internals.Errors.ErrorCode.None)
206                     throw ExceptionFactory.CreateException(ret);
207
208                 _bitOrder = value;
209             }
210         }
211
212         /// <summary>
213         /// Sets or gets the number of bits per word.
214         /// </summary>
215         /// <remarks>Get value is initialized after successful Set call.</remarks>
216         public byte BitsPerWord
217         {
218             get => _bitsPerWord;
219             set
220             {
221                 var ret = NativeSpi.SetBitsPerWord(_handle, value);
222                 if (ret != Internals.Errors.ErrorCode.None)
223                     throw ExceptionFactory.CreateException(ret);
224
225                 _bitsPerWord = value;
226             }
227         }
228
229         /// <summary>
230         /// Sets or gets the frequency of the SPI bus.
231         /// </summary>
232         /// <remarks>Get value is initialized after successful Set call.</remarks>
233         public uint ClockFrequency
234         {
235             get => _frequency;
236             set
237             {
238                 var ret = NativeSpi.SetFrequency(_handle, value);
239                 if (ret != Internals.Errors.ErrorCode.None)
240                     throw ExceptionFactory.CreateException(ret);
241
242                 _frequency = value;
243             }
244         }
245     }
246 }