/*
* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
*
* Licensed under the Apache License, Version 2.0 (the License);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an AS IS BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using NativeSpi = Interop.Peripheral.Spi;
namespace Tizen.Peripheral.Spi
{
///
/// Enumeration of SPI transfer modes.
///
public enum SpiMode
{
///
/// CPOL = 0, CPHa = 0 Mode.
///
Mode0 = 0,
///
/// CPOL = 0, CPHa = 1 Mode.
///
Mode1,
///
/// CPOL = 1, CPHa = 0 Mode.
///
Mode2,
///
/// CPOL = 1, CPHa = 1 Mode.
///
Mode3
}
///
/// Enumeration of bit orders.
///
///
/// Currently only LSB order is supported!
///
public enum BitOrder
{
///
/// Use most siginificant bit first.
///
MSB = 0,
///
/// Use least siginificant bit first.
///
LSB
}
///
/// The class allows applications to communicate via SPI platform's bus.
///
/// http://tizen.org/privilege/peripheralio
public class SpiDevice : IDisposable
{
//TODO Provide default values.
private SpiMode _transferMode;
private BitOrder _bitOrder;
private byte _bitsPerWord;
private uint _frequency;
///
/// Native handle to Spi.
///
private IntPtr _handle;
private bool _disposed = false;
///
/// Opens a SPI slave device.
///
/// The SPI bus number.
/// The SPI chip select number.
public SpiDevice(int bus, int chip)
{
var ret = NativeSpi.Open(bus, chip, out IntPtr handle);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
_handle = handle;
}
///
/// Closes the SPI slave device.
///
~SpiDevice()
{
Dispose(false);
}
///
/// Closes the SPI slave device.
///
public void Close() => Dispose();
///
/// Disposes the Spi.
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Disposes the Spi.
///
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
NativeSpi.Close(_handle);
_disposed = true;
}
///
/// Reads the bytes data from the SPI slave device.
///
/// The Data buffer.
public void Read(byte[] buffer)
{
var length = Convert.ToUInt32(buffer.Length);
var ret = NativeSpi.Read(_handle, buffer, length);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
}
///
/// Writes the bytes data to the SPI slave device.
///
/// The data buffer to write.
public void Write(byte[] data)
{
var length = Convert.ToUInt32(data.Length);
var ret = NativeSpi.Write(_handle, data, length);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
}
///
/// Exchanges the bytes data to the SPI slave device.
/// writeBuffer.Length and readBuffer.Length must be equal.
///
/// Array containing data to write to the device.
/// Array containing data read from the dievice.
public void TransferSequential(byte[] writeBuffer, byte[] readBuffer)
{
if (writeBuffer.Length != readBuffer.Length)
throw new Exception("writeBuffer.Length is not equal to readBuffer.Length");
var buffersLength = Convert.ToUInt32(writeBuffer.Length);
var ret = NativeSpi.Transfer(_handle, writeBuffer, readBuffer, buffersLength);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
}
///
/// Sets or gets the SPI transfer mode.
///
/// Get value is initialized after successful Set call.
public SpiMode Mode
{
get => _transferMode;
set
{
var ret = NativeSpi.SetMode(_handle, (NativeSpi.Mode)value);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
_transferMode = value;
}
}
///
/// Sets or gets the SPI bit order.
///
/// Get value is initialized after successful Set call.
public BitOrder BitOrder
{
get => _bitOrder;
set
{
var ret = NativeSpi.SetBitOrder(_handle, (NativeSpi.BitOrder)value);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
_bitOrder = value;
}
}
///
/// Sets or gets the number of bits per word.
///
/// Get value is initialized after successful Set call.
public byte BitsPerWord
{
get => _bitsPerWord;
set
{
var ret = NativeSpi.SetBitsPerWord(_handle, value);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
_bitsPerWord = value;
}
}
///
/// Sets or gets the frequency of the SPI bus.
///
/// Get value is initialized after successful Set call.
public uint ClockFrequency
{
get => _frequency;
set
{
var ret = NativeSpi.SetFrequency(_handle, value);
if (ret != Internals.Errors.ErrorCode.None)
throw ExceptionFactory.CreateException(ret);
_frequency = value;
}
}
}
}