summaryrefslogtreecommitdiff
path: root/bsp/nxp/mcx/mcxc/libraries/drivers/drv_spi.c
blob: 7e489916af129cba31276d47d2c5084169793509 (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
/*
 * Copyright (c) 2006-2024 RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-09-04     Yilin Sun    Initial version
 */

#include <rtdevice.h>

#include "fsl_spi.h"

#include "drv_spi.h"

#define BSP_DEFAULT_SPI_FREQUENCY (500000U)

typedef struct
{
    struct rt_spi_bus parent;
    SPI_Type *instance;
    uint32_t input_frequency;
} mcx_spi_obj_t;

typedef struct
{
    SPI_Type *instance;
    uint8_t id;
} mcx_spi_instance_t;

static const mcx_spi_instance_t mcx_spi_instances[] =
{
#ifdef BSP_USING_SPI0
    {SPI0, 0},
#endif
#ifdef BSP_USING_SPI1
    {SPI1, 1},
#endif
};

static mcx_spi_obj_t mcx_spi_list[ARRAY_SIZE(mcx_spi_instances)];

static rt_ssize_t mcx_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
    spi_transfer_t xfer =
    {
        .txData = message->send_buf,
        .rxData = message->recv_buf,
        .dataSize = message->length,
        .flags = 0UL,
    };

    mcx_spi_obj_t *spi = device->bus->parent.user_data;

    if (message->cs_take)
    {
        rt_pin_write(device->cs_pin, PIN_LOW);
    }

    SPI_MasterTransferBlocking(spi->instance, &xfer);

    if (message->cs_release)
    {
        rt_pin_write(device->cs_pin, PIN_HIGH);
    }

    return message->length;
}

static rt_err_t mcx_spi_configure(struct rt_spi_device *device, struct rt_spi_configuration *cfg)
{
    mcx_spi_obj_t *spi = device->bus->parent.user_data;

    SPI_MasterSetBaudRate(spi->instance, cfg->max_hz, spi->input_frequency);

    return RT_EOK;
}

static struct rt_spi_ops mcx_spi_ops =
{
    .configure = mcx_spi_configure,
    .xfer = mcx_spi_xfer,
};

rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint32_t pin)
{
    struct rt_spi_device *spi_device = rt_malloc(sizeof(struct rt_spi_device));
    if (!spi_device)
    {
        return -RT_ENOMEM;
    }

    return rt_spi_bus_attach_device_cspin(spi_device, device_name, bus_name, pin, NULL);
}

int rt_hw_spi_init(void)
{
    for (size_t i = 0; i < ARRAY_SIZE(mcx_spi_instances); i++)
    {
        char name_buf[16];

        /* TODO: Initialize SPI interface here. */

        mcx_spi_list[i].instance = mcx_spi_instances[i].instance;
        mcx_spi_list[i].input_frequency = CLOCK_GetCoreSysClkFreq();

        mcx_spi_list[i].parent.parent.user_data = &mcx_spi_list[i];

        spi_master_config_t cfg;
        SPI_MasterGetDefaultConfig(&cfg);

        SPI_MasterInit(mcx_spi_list[i].instance, &cfg, mcx_spi_list[i].input_frequency);

        rt_snprintf(name_buf, sizeof(name_buf), "spi%d", mcx_spi_instances[i].id);
        rt_spi_bus_register(&mcx_spi_list[i].parent, name_buf, &mcx_spi_ops);
    }

    return 0;
}

INIT_DEVICE_EXPORT(rt_hw_spi_init);