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