summaryrefslogtreecommitdiff
path: root/bsp/maxim/libraries/HAL_Drivers/drv_spi.c
blob: 960e02faa08fe1d961952e2a1a3318530e49f30e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date             Author          Notes
 * 2021-02-14       supperthomas    first version
 */

#include <stdint.h>
#include <string.h>
#include "board.h"
#include "drv_spi.h"

#define DBG_LEVEL   DBG_LOG
#include <rtdbg.h>
#define LOG_TAG                "drv.spi"

#ifdef BSP_USING_SPI

#if defined(BSP_USING_SPI0) || defined(BSP_USING_SPI1) || defined(BSP_USING_SPI2)
static struct mcu_drv_spi_config spi_config[] =
{
#ifdef BSP_USING_SPI0
    MCU_SPI0_CONFIG,
#endif
#ifdef BSP_USING_SPI1
    MCU_SPI1_CONFIG,
#endif

};

static struct mcu_drv_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])];


/**
  * @brief  This function config spi bus
  * @param  device
  * @param  configuration
  * @retval RT_EOK / -RT_ERROR
  */
static rt_err_t spi_configure(struct rt_spi_device *device,
                              struct rt_spi_configuration *configuration)
{
    RT_ASSERT(device != RT_NULL);
    RT_ASSERT(device->bus != RT_NULL);
    RT_ASSERT(device->bus->parent.user_data != RT_NULL);
    RT_ASSERT(configuration != RT_NULL);
    struct mcu_drv_spi *tmp_spi;
    tmp_spi = rt_container_of(device->bus, struct mcu_drv_spi, spi_bus);
    int mode;

    ///init

    switch (configuration->mode & RT_SPI_MODE_3)
    {
    case RT_SPI_MODE_0/* RT_SPI_CPOL:0 , RT_SPI_CPHA:0 */:
    case RT_SPI_MODE_1/* RT_SPI_CPOL:0 , RT_SPI_CPHA:1 */:
    case RT_SPI_MODE_2/* RT_SPI_CPOL:1 , RT_SPI_CPHA:0 */:
    case RT_SPI_MODE_3/* RT_SPI_CPOL:1 , RT_SPI_CPHA:1 */:
        mode = configuration->mode & RT_SPI_MODE_3;
        break;
    default:
        LOG_E("spi_configure mode error %x\n", configuration->mode);
        return -RT_ERROR;
    }

    tmp_spi->spixfer_req.width = SPI17Y_WIDTH_1;
    tmp_spi->spixfer_req.bits = configuration->data_width;
    tmp_spi->spixfer_req.ssel = 0;
    tmp_spi->spixfer_req.deass = 1;
    tmp_spi->spixfer_req.tx_num = 0;
    tmp_spi->spixfer_req.rx_num = 0;
    tmp_spi->spixfer_req.callback = NULL;
    LOG_D("spi init mode:%d, rate:%d", mode, configuration->max_hz);
    if (SPI_Init(tmp_spi->spi_instance, mode, configuration->max_hz) != 0)
    {
        LOG_E("Error configuring SPI\n");
        while (1) {}
    }
    //init
    return RT_EOK;
}

static rt_uint32_t spixfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
    RT_ASSERT(device != RT_NULL);
    RT_ASSERT(device->bus != RT_NULL);
    RT_ASSERT(device->bus->parent.user_data != RT_NULL);

    int ret = 0;
    struct mcu_drv_spi *tmp_spi;
    tmp_spi = rt_container_of(device->bus, struct mcu_drv_spi, spi_bus);


    tmp_spi->spixfer_req.tx_data = message->send_buf;
    tmp_spi->spixfer_req.rx_data = message->recv_buf;
    tmp_spi->spixfer_req.len = message->length;
    ret = SPI_MasterTrans(tmp_spi->spi_instance, &tmp_spi->spixfer_req);
    if (ret == E_NO_ERROR)
    {
        return message->length;
    }
    else
    {
        LOG_E("spixfer faild, ret %d", ret);
        return 0;
    }
}

/* spi bus callback function  */
static const struct rt_spi_ops nrfx_spi_ops =
{
    .configure = spi_configure,
    .xfer = spixfer,
};

/*spi bus init*/
static int rt_hw_spi_bus_init(void)
{
    rt_err_t result = -RT_ERROR;
    for (int i = 0; i < sizeof(spi_config) / sizeof(spi_config[0]); i++)
    {
        spi_bus_obj[i].spi_instance = spi_config[i].spi_instance;
        spi_bus_obj[i].spi_bus.parent.user_data = &spi_config[i];   //SPI INSTANCE
        result = rt_spi_bus_register(&spi_bus_obj[i].spi_bus, spi_config[i].bus_name, &nrfx_spi_ops);
        RT_ASSERT(result == RT_EOK);
    }
    return result;
}

int rt_hw_spi_init(void)
{
    return rt_hw_spi_bus_init();
}
INIT_BOARD_EXPORT(rt_hw_spi_init);

/**
  * Attach the spi device to SPI bus, this function must be used after initialization.
  */
rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t cs_pin)
{
    RT_ASSERT(bus_name != RT_NULL);
    RT_ASSERT(device_name != RT_NULL);
    RT_ASSERT(cs_pin != RT_NULL);

    rt_err_t result;
    struct rt_spi_device *spi_device;
    /* attach the device to spi bus*/
    spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
    RT_ASSERT(spi_device != RT_NULL);
    /* initialize the cs pin */
    result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, (void *)cs_pin);
    if (result != RT_EOK)
    {
        LOG_E("%s attach to %s faild, %d", device_name, bus_name, result);
        result = -RT_ERROR;
    }
    /* TODO: SET THE GPIO */

    RT_ASSERT(result == RT_EOK);
    return result;
}

#endif /* BSP_USING_SPI0 || BSP_USING_SPI1 || BSP_USING_SPI2 */
#endif /*BSP_USING_SPI*/