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"
19 const si24_opts_t *opts;
20 const si24_ioctl_t *ctl;
21 si24_event_handler_t eh;
25 static uint8_t _reg_read(si24_t *si, uint8_t reg,
26 uint8_t *data, int sz)
31 buf[0] = reg | SI24_R_REGISTER;
33 if (si->ctl->write_and_read(buf, sz+1) == -1) {
40 memcpy(data, (buf+1), sz);
45 static uint8_t _reg_write(si24_t *si, uint8_t reg,
46 const uint8_t *data, int sz)
50 buf[0] = reg | SI24_W_REGISTER;
51 memcpy((buf+1), data, sz);
53 if (si->ctl->write_and_read(buf, sz+1) == -1) {
63 static int _config(si24_t * si)
66 uint8_t config_reg = (1 << PWR_UP);
67 uint8_t feature_reg = 0x2; /* default value */
68 uint8_t rf_setup_reg = 0xE; /* default value */
69 uint8_t setup_retr_reg = 0x3; /* default value */
70 const uint8_t rf_ch_reg = 0x40; /* default value */
71 const si24_opts_t * params = si->opts;
73 if (params->enable_crc) {
74 config_reg |= (1 << EN_CRC);
75 config_reg |= (si->opts->crc << CRCO);
78 if (params->enable_ack) {
79 uint8_t dyn = (1 << DPL_P0);
80 ret += _reg_write(si, SI24_REG_DYNPD, &dyn, 1);
81 feature_reg |= (1 << EN_DYN_ACK);
82 ret += _reg_write(si, SI24_REG_FEATURE, &feature_reg, 1);
86 if (params->mac_addr & 0xF0000) {
88 ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
89 } else if (params->mac_addr & 0xF000) {
91 ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
94 ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
97 if (params->mode == SEND_MODE && params->enable_ack) {
98 ret += _reg_write(si, SI24_REG_RX_ADDR_P0, (uint8_t *) ¶ms->mac_addr, aw);
101 if (params->mode == RECV_MODE) {
102 config_reg |= (1 << PRIM_RX);
104 ret += _reg_write(si, SI24_REG_EN_RXADDR, &ch, 1);
105 ret += _reg_write(si, SI24_REG_RX_ADDR_P0, (uint8_t *) ¶ms->mac_addr, aw);
106 ret += _reg_write(si, SI24_REG_RX_PW_P0, (uint8_t *) ¶ms->payload, 1);
108 ret += _reg_write(si, SI24_REG_TX_ADDR, (uint8_t *) ¶ms->mac_addr, aw);
111 rf_setup_reg |= (params->speed << RF_DR_HIGH);
112 rf_setup_reg |= (params->txpwr << RF_PWR);
113 ret += _reg_write(si, SI24_REG_RF_SETUP, &rf_setup_reg, 1);
115 setup_retr_reg = ARD(params->timeout) | ARC(params->retries);
116 ret += _reg_write(si, SI24_REG_SETUP_RETR, &setup_retr_reg, 1);
118 ret += _reg_write(si, SI24_REG_RF_CH, &rf_ch_reg, 1);
119 ret += _reg_write(si, SI24_REG_CONFIG, &config_reg, 1);
124 si24_t* si24_init(const si24_opts_t *opts, si24_event_handler_t eh)
126 struct si24_t *si = (si24_t*) calloc(1, sizeof(si24_t));
131 si->ctl = opts->ioctl;
134 int ret = _config(si);
143 size_t si24_send(si24_t* si, const unsigned char * buf, size_t size)
146 uint16_t timeout = 0;
148 si24_status_reg_t flags;
150 if (si->opts->mode == RECV_MODE)
153 _reg_read(si, 0x7, (uint8_t *) &flags, 1);
155 if (flags.bits.TX_FULL) {
156 ev.type = EV_TX_FULL;
161 for (size_t idx = 0; idx < size; idx += si->opts->payload) {
162 sz = (size - idx) < si->opts->payload ? (size - idx) : si->opts->payload;
163 if (si->opts->enable_ack) {
164 _reg_write(si, SI24_W_TX_PAYLOAD, buf, sz);
165 while ((!flags.bits.TX_DS || !flags.bits.MAX_RT) && timeout < 1000) {
166 _reg_read(si, SI24_REG_STATUS, (uint8_t []){0x0}, 1);
169 if (flags.bits.MAX_RT) {
170 ev.type = EV_ERR_MAX_RETRIES;
177 _reg_write(si, SI24_W_TX_PAYLOAD_NO_ACK, buf, sz);
178 si->ctl->chip_enable(1);
179 while (!flags.bits.TX_DS && timeout < 1000) {
180 _reg_read(si, SI24_REG_STATUS, (uint8_t []){0x0}, 1);
185 if (timeout >= 1000) {
186 ev.type = EV_ERR_TIMEOUT;
194 si->ctl->chip_enable(0);
199 size_t si24_recv(si24_t* si, unsigned char * buf, size_t size)
203 if (si->opts->mode == SEND_MODE)
206 si24_status_reg_t flags;
207 _reg_read(si, 0x7, (uint8_t *) &flags, 1);
209 if (!flags.bits.RX_DR)
215 void si24_reset(si24_t* si)
217 si->ctl->chip_enable(0);
220 void si24_free(si24_t * si)