3 * Author : Robin Krens <robin@robinkrens.nl>
5 * Last Modified Date: 22.01.2023
6 * Last Modified By : Robin Krens <robin@robinkrens.nl>
16 #include "libsi24reg.h"
21 const si24_opts_t *opts;
22 const si24_ioctl_t *ctl;
23 si24_event_handler_t eh;
26 static uint8_t _reg_read(si24_t *si, uint8_t reg,
27 uint8_t *data, int sz)
32 buf[0] = reg | SI24_R_REGISTER;
35 if (si->ctl->write_and_read(buf, sz+1) == -1) {
42 memcpy(data, (buf+1), sz);
47 static uint8_t _reg_write(si24_t *si, uint8_t reg,
48 const uint8_t *data, int sz)
52 buf[0] = reg | SI24_W_REGISTER;
53 memcpy((buf+1), data, sz);
56 printf("REG 0x%x:\t", reg);
57 for (int i = 1; i <= sz; ++i) {
58 fprintf(stdout, "0x%x(%c)", buf[i], buf[i]);
60 fprintf(stdout, "\n");
63 if (si->ctl->write_and_read(buf, sz+1) == -1) {
73 static int _config(si24_t * si)
76 uint8_t config_reg = (1 << PWR_UP);
77 uint8_t feature_reg = 0x0; /* default value */
78 uint8_t rf_setup_reg = 0xE; /* default value */
79 uint8_t setup_retr_reg = 0x3; /* default value */
80 const uint8_t rf_ch_reg = 0x40; /* default value */
81 const si24_opts_t * params = si->opts;
83 if (params->enable_crc) {
84 config_reg |= (1 << EN_CRC);
85 config_reg |= (si->opts->crc << CRCO);
88 if (params->enable_ack) {
89 uint8_t dyn = (1 << DPL_P0);
90 ret += _reg_write(si, SI24_REG_DYNPD, &dyn, 1);
91 feature_reg |= (1 << EN_DPL);
92 ret += _reg_write(si, SI24_REG_FEATURE, &feature_reg, 1);
93 if (params->mode == SEND_MODE) {
94 setup_retr_reg = ARD(params->timeout) | ARC(params->retries);
95 ret += _reg_write(si, SI24_REG_SETUP_RETR, &setup_retr_reg, 1);
98 if (params->mode == SEND_MODE) {
99 feature_reg |= (1 << EN_DYN_ACK);
100 ret += _reg_write(si, SI24_REG_FEATURE, &feature_reg, 1);
105 if (params->mac_addr & 0xF0000) {
107 ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
108 } else if (params->mac_addr & 0xF000) {
110 ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
113 ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
119 if (params->mode == SEND_MODE && params->enable_ack) {
120 ret += _reg_write(si, SI24_REG_RX_ADDR_P0, (uint8_t *) ¶ms->mac_addr, aw);
123 if (params->mode == RECV_MODE) {
124 config_reg |= (1 << PRIM_RX);
126 ret += _reg_write(si, SI24_REG_EN_RXADDR, &ch, 1);
127 ret += _reg_write(si, SI24_REG_RX_ADDR_P0, (uint8_t *) ¶ms->mac_addr, aw);
128 ret += _reg_write(si, SI24_REG_RX_PW_P0, (uint8_t *) ¶ms->payload, 1);
130 ret += _reg_write(si, SI24_REG_TX_ADDR, (uint8_t *) ¶ms->mac_addr, aw);
133 rf_setup_reg |= (params->speed << RF_DR_HIGH);
134 rf_setup_reg |= (params->txpwr << RF_PWR);
135 ret += _reg_write(si, SI24_REG_RF_SETUP, &rf_setup_reg, 1);
138 ret += _reg_write(si, SI24_REG_RF_CH, &rf_ch_reg, 1);
139 ret += _reg_write(si, SI24_REG_CONFIG, &config_reg, 1);
144 si24_t* si24_init(const si24_opts_t *opts, si24_event_handler_t eh)
146 struct si24_t *si = (si24_t*) calloc(1, sizeof(si24_t));
151 si->ctl = opts->ioctl;
154 int ret = _config(si);
163 size_t si24_send(si24_t* si, const unsigned char * buf, size_t size)
166 uint16_t timeout = 0;
170 if (si->opts->mode == RECV_MODE)
173 _reg_read(si, SI24_REG_STATUS, (uint8_t *) &flags, 1);
175 if (flags & (1 << TX_FULL)) {
176 ev.type = EV_TX_FULL;
181 for (size_t idx = 0; idx < size; idx += si->opts->payload) {
182 sz = (size - idx) < si->opts->payload ? (size - idx) : si->opts->payload;
183 if (si->opts->enable_ack) {
184 _reg_write(si, SI24_W_TX_PAYLOAD, buf + idx, sz);
185 si->ctl->chip_enable(1);
186 while ((!(flags & (1 << TX_DS)) && !(flags & (1 << MAX_RT))) && timeout < 1000) {
187 _reg_read(si, SI24_REG_STATUS, &flags, 1);
190 if (flags & (1 << MAX_RT)) {
191 ev.type = EV_ERR_MAX_RETRIES;
198 _reg_write(si, SI24_W_TX_PAYLOAD_NO_ACK, buf + idx, sz);
199 si->ctl->chip_enable(1);
200 while (!(flags & (1 << TX_DS)) && timeout < 1000) {
201 _reg_read(si, SI24_REG_STATUS, &flags, 1);
206 if (timeout >= 1000) {
207 ev.type = EV_ERR_TIMEOUT;
216 ev.type = EV_TX_COMPLETE;
218 si->ctl->chip_enable(0);
223 size_t si24_recv(si24_t* si, unsigned char * buf, size_t size)
227 if (si->opts->mode == SEND_MODE)
231 _reg_read(si, 0x7, &flags, 1);
236 void si24_reset(si24_t* si)
238 if (si->opts->mode == RECV_MODE) {
239 _reg_write(si, SI24_FLUSH_RX, 0, 0);
241 else if (si->opts->mode == SEND_MODE) {
242 _reg_write(si, SI24_FLUSH_TX, 0, 0);
245 uint8_t status_reg = {0};
246 status_reg |= (1 << RX_DR);
247 status_reg |= (1 << TX_DS);
248 status_reg |= (1 << MAX_RT);
250 _reg_write(si, SI24_REG_STATUS, (uint8_t *) &status_reg, 1);
252 si->ctl->chip_enable(0);
255 void si24_free(si24_t * si)
260 /* hardware linkage */
261 int spi_w_r(unsigned char *data, size_t sz)
264 data[1] = (1 << TX_DS);
268 void ce(unsigned val)
272 void eh(si24_t *si, si24_event_t * e)
276 printf("SENT SUCCESFUL\n");
282 printf("EVENT: %x\n", e->type);
289 const unsigned char buf[] = "THIS IS A WIRELESS TEST MESSAGE!";
292 .write_and_read = spi_w_r,
296 const si24_opts_t opts = {
309 .mac_addr = 0xAAAAAAAAAA
312 struct si24_t * si = si24_init(&opts, eh);
313 si24_send(si, buf, sizeof(buf));