Skip to content

Commit dae6edb

Browse files
committed
libraries: SPI: Initial SPI implementation
- Tested controller mode on beagleconnect_freedom Signed-off-by: Ayush Singh <[email protected]>
1 parent 95e608f commit dae6edb

File tree

4 files changed

+167
-0
lines changed

4 files changed

+167
-0
lines changed

libraries/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
add_subdirectory(Wire)
4+
add_subdirectory(SPI)

libraries/SPI/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
zephyr_include_directories(.)
3+
4+
if(NOT DEFINED ARDUINO_BUILD_PATH)
5+
zephyr_sources_ifdef(CONFIG_SPI SPI.cpp)
6+
endif()

libraries/SPI/SPI.cpp

+101
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2024 Ayush Singh <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "SPI.h"
8+
#include <zephyr/kernel.h>
9+
10+
/* Serial Peripheral Control Register */
11+
uint8_t SPCR;
12+
13+
arduino::ZephyrSPI::ZephyrSPI(const struct device *spi) : spi_dev(spi) {}
14+
15+
uint8_t arduino::ZephyrSPI::transfer(uint8_t data) {
16+
int ret;
17+
uint8_t rx;
18+
const struct spi_buf tx_buf = {.buf = &data, .len = sizeof(data)};
19+
const struct spi_buf_set tx_buf_set = {
20+
.buffers = &tx_buf,
21+
.count = 1,
22+
};
23+
const struct spi_buf rx_buf = {.buf = &rx, .len = sizeof(rx)};
24+
const struct spi_buf_set rx_buf_set = {
25+
.buffers = &rx_buf,
26+
.count = 1,
27+
};
28+
29+
ret = spi_transceive(spi_dev, &config, &tx_buf_set, &rx_buf_set);
30+
if (ret < 0) {
31+
return 0;
32+
}
33+
34+
return rx;
35+
}
36+
37+
uint16_t arduino::ZephyrSPI::transfer16(uint16_t data) {
38+
int ret;
39+
uint16_t rx;
40+
const struct spi_buf tx_buf = {.buf = &data, .len = sizeof(data)};
41+
const struct spi_buf_set tx_buf_set = {
42+
.buffers = &tx_buf,
43+
.count = 1,
44+
};
45+
const struct spi_buf rx_buf = {.buf = &rx, .len = sizeof(rx)};
46+
const struct spi_buf_set rx_buf_set = {
47+
.buffers = &rx_buf,
48+
.count = 1,
49+
};
50+
51+
ret = spi_transceive(spi_dev, &config, &tx_buf_set, &rx_buf_set);
52+
if (ret < 0) {
53+
return 0;
54+
}
55+
56+
return rx;
57+
}
58+
59+
void arduino::ZephyrSPI::transfer(void *buf, size_t count) {
60+
int ret;
61+
const struct spi_buf tx_buf = {.buf = &buf, .len = count};
62+
const struct spi_buf_set tx_buf_set = {
63+
.buffers = &tx_buf,
64+
.count = 1,
65+
};
66+
67+
ret = spi_write(spi_dev, &config, &tx_buf_set);
68+
if (ret < 0) {
69+
return;
70+
}
71+
72+
ret = spi_read(spi_dev, &config, &tx_buf_set);
73+
if (ret < 0) {
74+
return;
75+
}
76+
}
77+
78+
void arduino::ZephyrSPI::usingInterrupt(int interruptNumber) {}
79+
80+
void arduino::ZephyrSPI::notUsingInterrupt(int interruptNumber) {}
81+
82+
void arduino::ZephyrSPI::beginTransaction(SPISettings settings) {
83+
memset(&config, 0, sizeof(config));
84+
config.frequency = settings.getClockFreq();
85+
config.operation = ((settings.getBitOrder() ^ 1) << 4) |
86+
(settings.getDataMode() << 1) | ((SPCR >> MSTR) & 1) |
87+
SPI_WORD_SET(8);
88+
}
89+
90+
void arduino::ZephyrSPI::endTransaction(void) { spi_release(spi_dev, &config); }
91+
92+
void arduino::ZephyrSPI::attachInterrupt() {}
93+
94+
void arduino::ZephyrSPI::detachInterrupt() {}
95+
96+
void arduino::ZephyrSPI::begin() {}
97+
98+
void arduino::ZephyrSPI::end() {}
99+
100+
arduino::ZephyrSPI
101+
SPI(DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), spis, 0)));

libraries/SPI/SPI.h

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2024 Ayush Singh <[email protected]>
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#pragma once
8+
9+
#include <Arduino.h>
10+
#include <api/HardwareSPI.h>
11+
#include <zephyr/drivers/spi.h>
12+
13+
#define SPR0 0
14+
#define SPR1 1
15+
#define CPHA 2
16+
#define CPOL 3
17+
#define MSTR 4
18+
#define DORD 5
19+
#define SPE 6
20+
#define SPIE 7
21+
22+
namespace arduino {
23+
class ZephyrSPI : public HardwareSPI {
24+
public:
25+
ZephyrSPI(const struct device *spi);
26+
27+
virtual uint8_t transfer(uint8_t data);
28+
virtual uint16_t transfer16(uint16_t data);
29+
virtual void transfer(void *buf, size_t count);
30+
31+
// Transaction Functions
32+
virtual void usingInterrupt(int interruptNumber);
33+
virtual void notUsingInterrupt(int interruptNumber);
34+
virtual void beginTransaction(SPISettings settings);
35+
virtual void endTransaction(void);
36+
37+
// SPI Configuration methods
38+
virtual void attachInterrupt();
39+
virtual void detachInterrupt();
40+
41+
virtual void begin();
42+
virtual void end();
43+
44+
private:
45+
const struct device *spi_dev;
46+
struct spi_config config;
47+
};
48+
49+
} // namespace arduino
50+
51+
extern arduino::ZephyrSPI SPI;
52+
/* Serial Peripheral Control Register */
53+
extern uint8_t SPCR;
54+
55+
using arduino::SPI_MODE0;
56+
using arduino::SPI_MODE1;
57+
using arduino::SPI_MODE2;
58+
using arduino::SPI_MODE3;
59+
using arduino::SPISettings;

0 commit comments

Comments
 (0)