uint16_t acc_magnitude(int8_t* angle) { int16_t acc[3], a, alpha; /* briefly turn on accelerometer */ acc_write(ACC_REG_CTRL_REG1, 0x97); timer_wait(MILLISECONDS(2)); acc_read(ACC_REG_OUT_X, sizeof(acc), (uint8_t*)&acc); acc_write(ACC_REG_CTRL_REG1, 0x00); /* get acceleration vector magnitude */ a = sqrt32( ((int)acc[0])*acc[0] + ((int)acc[1])*acc[1] + ((int)acc[2])*acc[2] )/64; /* calculate tag angle */ if(angle) { if(!a) alpha = 127; else { alpha = (acc[2]*2)/a; if(alpha>127) alpha=127; else if(alpha<-127) alpha=-127; } *angle = asin7deg(alpha); } return a; }
uint8_t acc_init(void) { int i; uint8_t data; /* initialize GPIO */ nrf_gpio_cfg_input(CONFIG_ACC_INT1, NRF_GPIO_PIN_NOPULL); nrf_gpio_cfg_input(CONFIG_ACC_MISO, NRF_GPIO_PIN_NOPULL); nrf_gpio_cfg_output(CONFIG_ACC_MOSI); nrf_gpio_cfg_output(CONFIG_ACC_SCK); nrf_gpio_cfg_output(CONFIG_ACC_nCS); /* mark inactive by default */ nrf_gpio_pin_set(CONFIG_ACC_nCS); /* configure peripheral */ SPI_ACC->PSELMISO = CONFIG_ACC_MISO; SPI_ACC->PSELMOSI = CONFIG_ACC_MOSI; SPI_ACC->PSELSCK = CONFIG_ACC_SCK; /* configure accelerometer for 8MHz */ SPI_ACC->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M8; SPI_ACC->CONFIG = (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos) |\ (SPI_CONFIG_CPHA_Trailing << SPI_CONFIG_CPHA_Pos) |\ (SPI_CONFIG_CPOL_ActiveLow << SPI_CONFIG_CPOL_Pos); /* reset events */ SPI_ACC->EVENTS_READY = 0U; /* enable SPI accelerometer peripheral */ SPI_ACC->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos); /* check accelerometer read */ acc_read(ACC_REG_WHO_AM_I, sizeof(data), &data); if(data!=0x33) return 1; /* initialize accelerometer */ for(i=0; i<ACC_INIT_COUNT; i++) acc_write(g_acc_init[i][0], g_acc_init[i][1]); return 0; }
/** * Flushes the content of the output-buffer. * The content of achat_channel::sendbuffer is written into achat_channel::fd. * * @param chan The channel * @return If the complete content of the output-buffer was written into the * filedescriptor achat_rc::ACHAT_RC_OK is returned. When there are * still some pending data left, achat_rc::ACHAT_RC_PENDING is returned. */ achat_rc acc_flush(struct achat_channel *chan) { void *buf; ssize_t bwritten, bsize; achat_rc ret; int error; ACC_CHKPARAM(chan != NULL); buf = acc_bufferptr(chan->sendbuffer); bsize = acc_bufferlen(chan->sendbuffer); if (bsize <= 0) { /* Nothing to do */ return ACHAT_RC_OK; } bwritten = acc_write(chan->fd, buf, bsize); error = errno; if (bwritten > 0) { achat_rc rc; /* Remove chunk of data from buffer */ rc = acc_bufferconsume(chan->sendbuffer, bwritten); if (rc != ACHAT_RC_OK) return ACHAT_RC_ERROR; } if (bwritten < 0) ret = (error == EAGAIN) ? ACHAT_RC_PENDING : ACHAT_RC_ERROR; else /* bwritten > 0 */ ret = (bwritten == bsize) ? ACHAT_RC_OK : ACHAT_RC_PENDING; if (ret == ACHAT_RC_PENDING && chan->event) { event_add(chan->event, NULL); ret = ACHAT_RC_OK; } return ret; }