13d0407baSopenharmony_ci/*
23d0407baSopenharmony_ci * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
33d0407baSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43d0407baSopenharmony_ci * you may not use this file except in compliance with the License.
53d0407baSopenharmony_ci * You may obtain a copy of the License at
63d0407baSopenharmony_ci *
73d0407baSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83d0407baSopenharmony_ci *
93d0407baSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103d0407baSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113d0407baSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123d0407baSopenharmony_ci * See the License for the specific language governing permissions and
133d0407baSopenharmony_ci * limitations under the License.
143d0407baSopenharmony_ci */
153d0407baSopenharmony_ci
163d0407baSopenharmony_ci/**
173d0407baSopenharmony_ci * @addtogroup Lockzhiner
183d0407baSopenharmony_ci *
193d0407baSopenharmony_ci * @file spi.h
203d0407baSopenharmony_ci */
213d0407baSopenharmony_ci
223d0407baSopenharmony_ci#ifndef LZ_HARDWARE_SPI_H
233d0407baSopenharmony_ci#define LZ_HARDWARE_SPI_H
243d0407baSopenharmony_ci
253d0407baSopenharmony_ci#include "stdint.h"
263d0407baSopenharmony_ci#include "stdbool.h"
273d0407baSopenharmony_ci/* SPI_CONFIG mode */
283d0407baSopenharmony_ci#define SPI_CPHA             (1<<0)                         /* bit[0]:CPHA, clock phase */
293d0407baSopenharmony_ci#define SPI_CPOL             (1<<1)                         /* bit[1]:CPOL, clock polarity */
303d0407baSopenharmony_ci/**
313d0407baSopenharmony_ci * At CPOL=0 the base value of the clock is zero
323d0407baSopenharmony_ci *  - For CPHA=0, data are captured on the clock's rising edge (low->high transition)
333d0407baSopenharmony_ci *    and data are propagated on a falling edge (high->low clock transition).
343d0407baSopenharmony_ci *  - For CPHA=1, data are captured on the clock's falling edge and data are
353d0407baSopenharmony_ci *    propagated on a rising edge.
363d0407baSopenharmony_ci * At CPOL=1 the base value of the clock is one (inversion of CPOL=0)
373d0407baSopenharmony_ci *  - For CPHA=0, data are captured on clock's falling edge and data are propagated
383d0407baSopenharmony_ci *    on a rising edge.
393d0407baSopenharmony_ci *  - For CPHA=1, data are captured on clock's rising edge and data are propagated
403d0407baSopenharmony_ci *    on a falling edge.
413d0407baSopenharmony_ci */
423d0407baSopenharmony_ci#define SPI_LSB              (0<<2)                         /* bit[2]: 0-LSB */
433d0407baSopenharmony_ci#define SPI_MSB              (1<<2)                         /* bit[2]: 1-MSB */
443d0407baSopenharmony_ci
453d0407baSopenharmony_ci#define SPI_MASTER           (0<<3)                         /* SPI master device */
463d0407baSopenharmony_ci#define SPI_SLAVE            (1<<3)                         /* SPI slave device */
473d0407baSopenharmony_ci
483d0407baSopenharmony_ci#define SPI_CSM_SHIFT        (4)
493d0407baSopenharmony_ci#define SPI_CSM_MASK         (0x3 << 4)                     /* SPI master ss_n hold cycles for MOTO SPI master */
503d0407baSopenharmony_ci
513d0407baSopenharmony_ci#define SPI_MODE_0           (0 | 0)                        /* CPOL = 0, CPHA = 0 */
523d0407baSopenharmony_ci#define SPI_MODE_1           (0 | SPI_CPHA)              /* CPOL = 0, CPHA = 1 */
533d0407baSopenharmony_ci#define SPI_MODE_2           (SPI_CPOL | 0)              /* CPOL = 1, CPHA = 0 */
543d0407baSopenharmony_ci#define SPI_MODE_3           (SPI_CPOL | SPI_CPHA)    /* CPOL = 1, CPHA = 1 */
553d0407baSopenharmony_ci#define SPI_MODE_MASK        (SPI_CPHA | SPI_CPOL | SPI_MSB)
563d0407baSopenharmony_ci#define SPI_INT_TXFIM (1 << SPI_IMR_TXFIM_SHIFT)
573d0407baSopenharmony_cienum {
583d0407baSopenharmony_ci    SPI_PERWORD_8BITS,
593d0407baSopenharmony_ci    SPI_PERWORD_16BITS,
603d0407baSopenharmony_ci};
613d0407baSopenharmony_ci
623d0407baSopenharmony_cienum {
633d0407baSopenharmony_ci    SPI_CMS_ZERO_CYCLES = 0,
643d0407baSopenharmony_ci    SPI_CMS_HALF_CYCLES,
653d0407baSopenharmony_ci    SPI_CMS_ONE_CYCLES,
663d0407baSopenharmony_ci};
673d0407baSopenharmony_ci
683d0407baSopenharmony_ci/**
693d0407baSopenharmony_ci * @ingroup LzSpiConfig
703d0407baSopenharmony_ci *
713d0407baSopenharmony_ci *
723d0407baSopenharmony_ci *
733d0407baSopenharmony_ci * @bitsPerWord Indicates select a bits_per_word for transfer.
743d0407baSopenharmony_ci * @firstBit: Indicates whether data transfers start from MSB or LSB bit.
753d0407baSopenharmony_ci * @mode Indicates the clock polarity(SCPOL) and clock phase(SCPH).
763d0407baSopenharmony_ci * 0: SCPH=0 SCPOL=0
773d0407baSopenharmony_ci * 1: SCPH=0 SCPOL=1
783d0407baSopenharmony_ci * 2: SCPH=1 SCPOL=0
793d0407baSopenharmony_ci * 3: SCPH=1 SCPOL=1
803d0407baSopenharmony_ci * @speed Indicates the Baud Rate prescaler value which will be
813d0407baSopenharmony_ci    used to configure the transmit and receive SCK clock, unit Hz.
823d0407baSopenharmony_ci * @nCycles: Specifies Motorola SPI Master SS_N high cycles for each frame data is transfer.
833d0407baSopenharmony_ci * @isSlave Indictates Whether spi work as slave mode.
843d0407baSopenharmony_ci */
853d0407baSopenharmony_citypedef struct _LzSpiConfig {
863d0407baSopenharmony_ci    unsigned int bitsPerWord;
873d0407baSopenharmony_ci    unsigned int firstBit;
883d0407baSopenharmony_ci    unsigned int mode;
893d0407baSopenharmony_ci    unsigned int speed;
903d0407baSopenharmony_ci    unsigned int nCycles;
913d0407baSopenharmony_ci    unsigned int csm;
923d0407baSopenharmony_ci    bool isSlave;
933d0407baSopenharmony_ci} LzSpiConfig;
943d0407baSopenharmony_ci
953d0407baSopenharmony_ci/**
963d0407baSopenharmony_ci * @ingroup LzSpiMsg
973d0407baSopenharmony_ci *
983d0407baSopenharmony_ci *
993d0407baSopenharmony_ci * @chn: Indicates the spi channel based on CSn.
1003d0407baSopenharmony_ci * @csTake: Indicates take the CS signal.
1013d0407baSopenharmony_ci * @csRelease: Indicates release the CS signal.
1023d0407baSopenharmony_ci * @txBuf Indicates the data to be written, or NULL.
1033d0407baSopenharmony_ci * @rxBuf Indicates the data to be read, or NULL.
1043d0407baSopenharmony_ci * @len Indicates the bytes of data to transfer.
1053d0407baSopenharmony_ci */
1063d0407baSopenharmony_citypedef struct _LzSpiMsg {
1073d0407baSopenharmony_ci    unsigned int chn;
1083d0407baSopenharmony_ci    bool csTake;
1093d0407baSopenharmony_ci    bool csRelease;
1103d0407baSopenharmony_ci    const void *txBuf;
1113d0407baSopenharmony_ci    void *rxBuf;
1123d0407baSopenharmony_ci    unsigned int len;
1133d0407baSopenharmony_ci} LzSpiMsg;
1143d0407baSopenharmony_ci
1153d0407baSopenharmony_ci/**
1163d0407baSopenharmony_ci * @brief Sets configure information for an SPI device.
1173d0407baSopenharmony_ci *
1183d0407baSopenharmony_ci * @param id Indicates the SPI device ID.
1193d0407baSopenharmony_ci * @param conf Indicates the SPI configure to set.
1203d0407baSopenharmony_ci * @return Returns {@link LZ_HARDWARE_SUCCESS} if the configure is set;
1213d0407baSopenharmony_ci * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
1223d0407baSopenharmony_ci */
1233d0407baSopenharmony_ciunsigned int LzSpiSetConfig(unsigned int id, LzSpiConfig conf);
1243d0407baSopenharmony_ci
1253d0407baSopenharmony_ci/**
1263d0407baSopenharmony_ci * @brief Initializes an SPI device with a specified transfer speed.
1273d0407baSopenharmony_ci *
1283d0407baSopenharmony_ci *
1293d0407baSopenharmony_ci *
1303d0407baSopenharmony_ci * @param id Indicates the SPI device ID.
1313d0407baSopenharmony_ci * @param conf Indicates the SPI configure to set.
1323d0407baSopenharmony_ci * @return Returns {@link LZ_HARDWARE_SUCCESS} if the SPI device is initialized;
1333d0407baSopenharmony_ci * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
1343d0407baSopenharmony_ci */
1353d0407baSopenharmony_ciunsigned int LzSpiInit(unsigned int id, LzSpiConfig conf);
1363d0407baSopenharmony_ci
1373d0407baSopenharmony_ci/**
1383d0407baSopenharmony_ci * @brief Deinitializes an SPI device.
1393d0407baSopenharmony_ci *
1403d0407baSopenharmony_ci * @param id Indicates the SPI device ID.
1413d0407baSopenharmony_ci * @return Returns {@link LZ_HARDWARE_SUCCESS} if the SPI device is deinitialized;
1423d0407baSopenharmony_ci * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
1433d0407baSopenharmony_ci */
1443d0407baSopenharmony_ciunsigned int LzSpiDeinit(unsigned int id);
1453d0407baSopenharmony_ci
1463d0407baSopenharmony_ci/**
1473d0407baSopenharmony_ci * @brief transfer data with an SPI device.
1483d0407baSopenharmony_ci *
1493d0407baSopenharmony_ci *
1503d0407baSopenharmony_ci *
1513d0407baSopenharmony_ci * @param id Indicates the SPI device ID.
1523d0407baSopenharmony_ci * @param msg Indicates the pointer to the message.
1533d0407baSopenharmony_ci * @return Returns {@link LZ_HARDWARE_SUCCESS} if the data is written to the SPI device successfully;
1543d0407baSopenharmony_ci * returns {@link LZ_HARDWARE_FAILURE} otherwise. For details about other return values, see the chip description.
1553d0407baSopenharmony_ci */
1563d0407baSopenharmony_ciunsigned int LzSpiTransfer(unsigned int id, LzSpiMsg *msg);
1573d0407baSopenharmony_ci
1583d0407baSopenharmony_cistatic inline unsigned int LzSpiRead(unsigned int id, unsigned int chn, void *buf, unsigned int len)
1593d0407baSopenharmony_ci{
1603d0407baSopenharmony_ci    LzSpiMsg msg;
1613d0407baSopenharmony_ci
1623d0407baSopenharmony_ci    msg.chn = chn;
1633d0407baSopenharmony_ci    msg.csTake = true;
1643d0407baSopenharmony_ci    msg.csRelease = true;
1653d0407baSopenharmony_ci    msg.txBuf = NULL;
1663d0407baSopenharmony_ci    msg.rxBuf = buf;
1673d0407baSopenharmony_ci    msg.len = len;
1683d0407baSopenharmony_ci
1693d0407baSopenharmony_ci    return LzSpiTransfer(id, &msg);
1703d0407baSopenharmony_ci}
1713d0407baSopenharmony_ci
1723d0407baSopenharmony_cistatic inline unsigned int LzSpiWrite(unsigned int id, unsigned int chn, const void *buf, unsigned int len)
1733d0407baSopenharmony_ci{
1743d0407baSopenharmony_ci    LzSpiMsg msg;
1753d0407baSopenharmony_ci
1763d0407baSopenharmony_ci    msg.chn = chn;
1773d0407baSopenharmony_ci    msg.csTake = true;
1783d0407baSopenharmony_ci    msg.csRelease = true;
1793d0407baSopenharmony_ci    msg.txBuf = buf;
1803d0407baSopenharmony_ci    msg.rxBuf = NULL;
1813d0407baSopenharmony_ci    msg.len = len;
1823d0407baSopenharmony_ci
1833d0407baSopenharmony_ci    return LzSpiTransfer(id, &msg);
1843d0407baSopenharmony_ci}
1853d0407baSopenharmony_ci
1863d0407baSopenharmony_cistatic inline unsigned int LzSpiWriteAndRead(unsigned int id, unsigned int chn,
1873d0407baSopenharmony_ci                                             const void *txBuf, void *rxBuf,
1883d0407baSopenharmony_ci                                             unsigned int len)
1893d0407baSopenharmony_ci{
1903d0407baSopenharmony_ci    LzSpiMsg msg;
1913d0407baSopenharmony_ci
1923d0407baSopenharmony_ci    msg.chn = chn;
1933d0407baSopenharmony_ci    msg.csTake = true;
1943d0407baSopenharmony_ci    msg.csRelease = true;
1953d0407baSopenharmony_ci    msg.txBuf = txBuf;
1963d0407baSopenharmony_ci    msg.rxBuf = rxBuf;
1973d0407baSopenharmony_ci    msg.len = len;
1983d0407baSopenharmony_ci
1993d0407baSopenharmony_ci    return LzSpiTransfer(id, &msg);
2003d0407baSopenharmony_ci}
2013d0407baSopenharmony_ci
2023d0407baSopenharmony_cistatic inline unsigned int LzSpiWriteThenRead(unsigned int id, unsigned int chn,
2033d0407baSopenharmony_ci                                              const void *txBuf, unsigned int txLen,
2043d0407baSopenharmony_ci                                              void *rxBuf, unsigned int rxLen)
2053d0407baSopenharmony_ci{
2063d0407baSopenharmony_ci    int ret;
2073d0407baSopenharmony_ci    LzSpiMsg msg;
2083d0407baSopenharmony_ci
2093d0407baSopenharmony_ci    msg.chn = chn;
2103d0407baSopenharmony_ci    msg.csTake = true;
2113d0407baSopenharmony_ci    msg.csRelease = false;
2123d0407baSopenharmony_ci    msg.txBuf = txBuf;
2133d0407baSopenharmony_ci    msg.rxBuf = NULL;
2143d0407baSopenharmony_ci    msg.len = txLen;
2153d0407baSopenharmony_ci
2163d0407baSopenharmony_ci    ret = LzSpiTransfer(id, &msg);
2173d0407baSopenharmony_ci    if (ret != LZ_HARDWARE_SUCCESS) {
2183d0407baSopenharmony_ci        return ret;
2193d0407baSopenharmony_ci    }
2203d0407baSopenharmony_ci
2213d0407baSopenharmony_ci    msg.chn = chn;
2223d0407baSopenharmony_ci    msg.csTake = false;
2233d0407baSopenharmony_ci    msg.csRelease = true;
2243d0407baSopenharmony_ci    msg.txBuf = NULL;
2253d0407baSopenharmony_ci    msg.rxBuf = rxBuf;
2263d0407baSopenharmony_ci    msg.len = rxLen;
2273d0407baSopenharmony_ci
2283d0407baSopenharmony_ci    return LzSpiTransfer(id, &msg);
2293d0407baSopenharmony_ci}
2303d0407baSopenharmony_ci
2313d0407baSopenharmony_ci#endif