1 /*
2 * Copyright (c) 2015 Eric Holland
3 *
4 * Use of this source code is governed by a MIT-style
5 * license that can be found in the LICENSE file or at
6 * https://opensource.org/licenses/MIT
7 */
8 #include <lk/err.h>
9 #include <kernel/mutex.h>
10 #include <platform/gpio.h>
11 #include <target/gpioconfig.h>
12 #include <target/bmi055.h>
13 #include <target/sensor_bus.h>
14 #include <dev/accelerometer.h>
15
16 static mutex_t sensorbus_mutex;
17 static SPI_HandleTypeDef spi_handle;
18
19 static uint8_t tx_buff[16];
20 static uint8_t rx_buff[16];
21
acc_read_xyz(position_vector_t * pos_vector_p)22 status_t acc_read_xyz(position_vector_t *pos_vector_p) {
23 tx_buff[0] = BMI055_ADDRESS_READ( BMI055_ACC_ACCD_X_LSB );
24 if ( acc_flush(tx_buff, rx_buff, 7) == NO_ERROR ) {
25 pos_vector_p->x = 0.001*(((int8_t)rx_buff[2] << 4) | ( (rx_buff[1] >> 4) & 0x0F));
26 pos_vector_p->y = 0.001*(((int8_t)rx_buff[4] << 4) | ( (rx_buff[3] >> 4) & 0x0F));
27 pos_vector_p->z = 0.001*(((int8_t)rx_buff[6] << 4) | ( (rx_buff[5] >> 4) & 0x0F));
28 return NO_ERROR;
29 } else {
30 return ERR_GENERIC;
31 }
32 }
33
acc_flush(uint8_t * tbuff,uint8_t * rbuff,uint8_t numbytes)34 status_t acc_flush(uint8_t *tbuff, uint8_t *rbuff, uint8_t numbytes) {
35 status_t ret_status;
36
37 mutex_acquire(&sensorbus_mutex);
38
39 gpio_set(GPIO_ACC_nCS,GPIO_PIN_RESET);
40
41 ret_status = HAL_SPI_TransmitReceive(&spi_handle, tbuff, rbuff, numbytes, 5000);
42
43 gpio_set(GPIO_ACC_nCS,GPIO_PIN_SET);
44
45 mutex_release(&sensorbus_mutex);
46
47 return ret_status;
48 }
49
50 /**
51 * @brief Initiale SPI5 module and IO for control of spi bus linking nrf51, accelerometer, and gyroscope.
52 *
53 */
sensor_bus_init_early(void)54 status_t sensor_bus_init_early(void) {
55 __HAL_SENSOR_BUS_GPIO_CLK_ENABLE();
56 __HAL_RCC_SPI5_CLK_ENABLE();
57
58 gpio_config(GPIO_SPI5_SCK, GPIO_STM32_AF | GPIO_STM32_AFn(GPIO_AF5_SPI5) | GPIO_PULLUP);
59 gpio_config(GPIO_SPI5_MISO, GPIO_STM32_AF | GPIO_STM32_AFn(GPIO_AF5_SPI5) | GPIO_PULLUP);
60 gpio_config(GPIO_SPI5_MOSI, GPIO_STM32_AF | GPIO_STM32_AFn(GPIO_AF5_SPI5) | GPIO_PULLUP);
61
62 gpio_config(GPIO_NRF_CS, GPIO_OUTPUT );
63 gpio_config(GPIO_NRF_INT, GPIO_INPUT | GPIO_PULLUP);
64
65 gpio_config(GPIO_GYRO_nCS, GPIO_OUTPUT );
66 gpio_config(GPIO_GYRO_INT, GPIO_INPUT | GPIO_PULLUP);
67
68 gpio_config(GPIO_ACC_nCS, GPIO_OUTPUT );
69 gpio_config(GPIO_ACC_INT, GPIO_INPUT | GPIO_PULLUP);
70
71 gpio_set(GPIO_NRF_CS, GPIO_PIN_RESET);
72 gpio_set(GPIO_GYRO_nCS, GPIO_PIN_SET);
73 gpio_set(GPIO_ACC_nCS, GPIO_PIN_SET);
74
75 spi_handle.Instance = SPI5;
76 spi_handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;
77 spi_handle.Init.Direction = SPI_DIRECTION_2LINES;
78 spi_handle.Init.CLKPhase = SPI_PHASE_1EDGE;
79 spi_handle.Init.CLKPolarity = SPI_POLARITY_LOW;
80 spi_handle.Init.DataSize = SPI_DATASIZE_8BIT;
81 spi_handle.Init.FirstBit = SPI_FIRSTBIT_MSB;
82 spi_handle.Init.TIMode = SPI_TIMODE_DISABLE;
83 spi_handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
84 spi_handle.Init.CRCPolynomial = 7;
85 spi_handle.Init.NSS = SPI_NSS_SOFT;
86 spi_handle.Init.Mode = SPI_MODE_MASTER;
87
88 if (HAL_SPI_Init(&spi_handle) != HAL_OK) {
89 return ERR_GENERIC;
90 }
91 return NO_ERROR;
92 }
93
94
95
sensor_bus_init(void)96 void sensor_bus_init(void) {
97 mutex_init(&sensorbus_mutex);
98 }
99
100
101