+static uint8_t _reg_read(si24_t *si, uint8_t reg,
+ uint8_t *data, int sz)
+{
+ uint8_t buf[sz+1];
+
+ memset(buf, 0, sz+1);
+ buf[0] = reg | SI24_R_REGISTER;
+
+ if (si->ctl->write_and_read(buf, sz+1) == -1) {
+ si24_event_t ev;
+ ev.type = EV_ERR_BUS;
+ si->eh(si, &ev);
+ return -1;
+ }
+
+ memcpy(data, (buf+1), sz);
+
+ return 0;
+}
+
+static uint8_t _reg_write(si24_t *si, uint8_t reg,
+ const uint8_t *data, int sz)
+{
+ uint8_t buf[sz+1];
+
+ buf[0] = reg | SI24_W_REGISTER;
+ memcpy((buf+1), data, sz);
+
+ if (si->ctl->write_and_read(buf, sz+1) == -1) {
+ si24_event_t ev;
+ ev.type = EV_ERR_BUS;
+ si->eh(si, &ev);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int _config(si24_t * si)
+{
+ int ret = 0;
+ uint8_t config_reg = (1 << PWR_UP);
+ uint8_t feature_reg = 0x2; /* default value */
+ uint8_t rf_setup_reg = 0xE; /* default value */
+ uint8_t setup_retr_reg = 0x3; /* default value */
+ const uint8_t rf_ch_reg = 0x40; /* default value */
+ const si24_opts_t * params = si->opts;
+
+ if (params->enable_crc) {
+ config_reg |= (1 << EN_CRC);
+ config_reg |= (si->opts->crc << CRCO);
+ }
+
+ if (params->enable_ack) {
+ uint8_t dyn = (1 << DPL_P0);
+ ret += _reg_write(si, SI24_REG_DYNPD, &dyn, 1);
+ feature_reg |= (1 << EN_DYN_ACK);
+ ret += _reg_write(si, SI24_REG_FEATURE, &feature_reg, 1);
+ }
+
+ uint8_t aw;
+ if (params->mac_addr & 0xF0000) {
+ aw = AW_5;
+ ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
+ } else if (params->mac_addr & 0xF000) {
+ aw = AW_4;
+ ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
+ } else {
+ aw = AW_3;
+ ret += _reg_write(si, SI24_REG_SETUP_AW, &aw, 1);
+ }
+
+ if (params->mode == SEND_MODE && params->enable_ack) {
+ ret += _reg_write(si, SI24_REG_RX_ADDR_P0, (uint8_t *) ¶ms->mac_addr, aw);
+ }
+
+ if (params->mode == RECV_MODE) {
+ config_reg |= (1 << PRIM_RX);
+ uint8_t ch = 0x1;
+ ret += _reg_write(si, SI24_REG_EN_RXADDR, &ch, 1);
+ ret += _reg_write(si, SI24_REG_RX_ADDR_P0, (uint8_t *) ¶ms->mac_addr, aw);
+ ret += _reg_write(si, SI24_REG_RX_PW_P0, (uint8_t *) ¶ms->payload, 1);
+ } else {
+ ret += _reg_write(si, SI24_REG_TX_ADDR, (uint8_t *) ¶ms->mac_addr, aw);
+ }
+
+ rf_setup_reg |= (params->speed << RF_DR_HIGH);
+ rf_setup_reg |= (params->txpwr << RF_PWR);
+ ret += _reg_write(si, SI24_REG_RF_SETUP, &rf_setup_reg, 1);
+
+ setup_retr_reg = ARD(params->timeout) | ARC(params->retries);
+ ret += _reg_write(si, SI24_REG_SETUP_RETR, &setup_retr_reg, 1);
+
+ ret += _reg_write(si, SI24_REG_RF_CH, &rf_ch_reg, 1);
+ ret += _reg_write(si, SI24_REG_CONFIG, &config_reg, 1);
+
+ return ret;
+}
+