acc_hal_integration_stm32cube_xm.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2022-2023
2 // All rights reserved
3 // This file is subject to the terms and conditions defined in the file
4 // 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
5 // of this source code package.
6
7 #include <stdarg.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <string.h>
12
13 #include "main.h"
14
15 #include "acc_definitions_common.h"
16 #include "acc_hal_definitions_a121.h"
17 #include "acc_hal_integration_a121.h"
18 #include "acc_integration.h"
19 #include "acc_integration_log.h"
20
21 /* spi handle */
22 extern SPI_HandleTypeDef A121_SPI_HANDLE;
23
24 /**
25 * @brief The number of sensors available on the board
26 */
27 #define SENSOR_COUNT 1
28
29 /**
30 * @brief Size of SPI transfer buffer
31 */
32 #ifndef STM32_MAX_TRANSFER_SIZE
33 #define STM32_MAX_TRANSFER_SIZE 65535
34 #endif
35
36
37 static inline void disable_interrupts(void)
38 {
39 __disable_irq();
40 }
41
42
43 static inline void enable_interrupts(void)
44 {
45 __enable_irq();
46 __ISB();
47 }
48
49
50 #ifdef A121_USE_SPI_DMA
51 static volatile bool spi_transfer_complete;
52
53
54 void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *h_spi)
55 {
56 (void)h_spi;
57 spi_transfer_complete = true;
58 }
59
60
61 #endif
62
63 //----------------------------------------
64 // Implementation of RSS HAL handlers
65 //----------------------------------------
66
67
68 static void acc_hal_integration_sensor_transfer16(acc_sensor_id_t sensor_id, uint16_t *buffer, size_t buffer_length)
69
70
71 {
72 (void)sensor_id; // Ignore parameter sensor_id
73
74 const uint32_t SPI_TRANSMIT_RECEIVE_TIMEOUT = 5000;
75
76 #ifdef A121_USE_SPI_DMA
77 spi_transfer_complete = false;
78 HAL_StatusTypeDef status = HAL_SPI_TransmitReceive_DMA(&A121_SPI_HANDLE, (uint8_t *)buffer, (uint8_t *)buffer, buffer_length);
79
80 if (status != HAL_OK)
81 {
82 return;
83 }
84
85 uint32_t start = HAL_GetTick();
86
87 while (!spi_transfer_complete && (HAL_GetTick() - start) < SPI_TRANSMIT_RECEIVE_TIMEOUT)
88 {
89 // Turn off interrupts
90 disable_interrupts();
91 // Check once more so that the interrupt have not occurred
92 if (!spi_transfer_complete)
93 {
94 __WFI();
95 }
96
97 // Enable interrupt again, the ISR will execute directly after this
98 enable_interrupts();
99 }
100 #else
101 HAL_SPI_TransmitReceive(&A121_SPI_HANDLE, (uint8_t *)buffer, (uint8_t *)buffer, buffer_length, SPI_TRANSMIT_RECEIVE_TIMEOUT);
102
103 #endif
104 }
105
106
107 void acc_hal_integration_sensor_supply_on(acc_sensor_id_t sensor_id)
108 {
109 (void)sensor_id; // Ignore parameter sensor_id
110 }
111
112
113 void acc_hal_integration_sensor_supply_off(acc_sensor_id_t sensor_id)
114 {
115 (void)sensor_id; // Ignore parameter sensor_id
116 }
117
118
119 void acc_hal_integration_sensor_enable(acc_sensor_id_t sensor_id)
120 {
121 (void)sensor_id; // Ignore parameter sensor_id
122
123 HAL_GPIO_WritePin(ENABLE_GPIO_Port, ENABLE_Pin, GPIO_PIN_SET);
124
125 // Wait 2 ms to make sure that the sensor crystal have time to stabilize
126 acc_integration_sleep_ms(2);
127 }
128
129
130 void acc_hal_integration_sensor_disable(acc_sensor_id_t sensor_id)
131 {
132 (void)sensor_id; // Ignore parameter sensor_id
133
134 HAL_GPIO_WritePin(ENABLE_GPIO_Port, ENABLE_Pin, GPIO_PIN_RESET);
135
136 // Wait after disable to leave the sensor in a known state
137 // in case the application intends to enable the sensor directly
138 acc_integration_sleep_ms(2);
139 }
140
141
142 bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms)
143 {
144 (void)sensor_id; // Ignore parameter sensor_id
145
146 const uint32_t wait_begin_ms = HAL_GetTick();
147 while ((HAL_GPIO_ReadPin(INTERRUPT_GPIO_Port, INTERRUPT_Pin) != GPIO_PIN_SET) &&
148 (HAL_GetTick() - wait_begin_ms < timeout_ms))
149 {
150 // Wait for the GPIO interrupt
151 disable_interrupts();
152 // Check again so that IRQ did not occur
153 if (HAL_GPIO_ReadPin(INTERRUPT_GPIO_Port, INTERRUPT_Pin) != GPIO_PIN_SET)
154 {
155 __WFI();
156 }
157
158 // Enable interrupts again to allow pending interrupt to be handled
159 enable_interrupts();
160 }
161
162 return HAL_GPIO_ReadPin(INTERRUPT_GPIO_Port, INTERRUPT_Pin) == GPIO_PIN_SET;
163 }
164
165
166 const acc_hal_a121_t *acc_hal_rss_integration_get_implementation(void)
167 {
168 static const acc_hal_a121_t val =
169 {
170 .max_spi_transfer_size = STM32_MAX_TRANSFER_SIZE,
171
172 .mem_alloc = malloc,
173 .mem_free = free,
174
175 .transfer = NULL,
176 .log = acc_integration_log,
177
178 .optimization.transfer16 = acc_hal_integration_sensor_transfer16,
179 };
180
181 return &val;
182 }
183
184
185 uint16_t acc_hal_integration_sensor_count(void)
186 {
187 return SENSOR_COUNT;
188 }
acc_hal_integration_sensor_supply_on
void acc_hal_integration_sensor_supply_on(acc_sensor_id_t sensor_id)
Power on sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:107
STM32_MAX_TRANSFER_SIZE
#define STM32_MAX_TRANSFER_SIZE
Size of SPI transfer buffer.
Definition: acc_hal_integration_stm32cube_xm.c:33
acc_hal_integration_wait_for_sensor_interrupt
bool acc_hal_integration_wait_for_sensor_interrupt(acc_sensor_id_t sensor_id, uint32_t timeout_ms)
Wait for a sensor interrupt.
Definition: acc_hal_integration_stm32cube_xm.c:142
acc_hal_integration_sensor_supply_off
void acc_hal_integration_sensor_supply_off(acc_sensor_id_t sensor_id)
Power off sensor supply.
Definition: acc_hal_integration_stm32cube_xm.c:113
acc_integration_log
void acc_integration_log(acc_log_level_t level, const char *module, const char *format,...)
Log function.
Definition: acc_exploration_server_stm32.c:220
acc_integration.h
ENABLE_GPIO_Port
#define ENABLE_GPIO_Port
Definition: main.h:85
disable_interrupts
static void disable_interrupts(void)
Definition: acc_hal_integration_stm32cube_xm.c:37
SENSOR_COUNT
#define SENSOR_COUNT
The number of sensors available on the board.
Definition: acc_hal_integration_stm32cube_xm.c:27
acc_hal_a121_t
Definition: acc_hal_definitions_a121.h:82
acc_integration_sleep_ms
void acc_integration_sleep_ms(uint32_t time_msec)
Sleep for a specified number of milliseconds.
Definition: acc_integration_stm32.c:501
A121_SPI_HANDLE
SPI_HandleTypeDef A121_SPI_HANDLE
acc_hal_integration_a121.h
acc_hal_integration_sensor_transfer16
static void acc_hal_integration_sensor_transfer16(acc_sensor_id_t sensor_id, uint16_t *buffer, size_t buffer_length)
Definition: acc_hal_integration_stm32cube_xm.c:68
acc_hal_integration_sensor_disable
void acc_hal_integration_sensor_disable(acc_sensor_id_t sensor_id)
Disable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:130
acc_hal_definitions_a121.h
acc_hal_integration_sensor_count
uint16_t acc_hal_integration_sensor_count(void)
Get the max number of sensors the integration supports.
Definition: acc_hal_integration_stm32cube_xm.c:185
acc_hal_rss_integration_get_implementation
const acc_hal_a121_t * acc_hal_rss_integration_get_implementation(void)
Get hal implementation reference.
Definition: acc_hal_integration_stm32cube_xm.c:166
ENABLE_Pin
#define ENABLE_Pin
Definition: main.h:84
acc_hal_integration_sensor_enable
void acc_hal_integration_sensor_enable(acc_sensor_id_t sensor_id)
Enable sensor.
Definition: acc_hal_integration_stm32cube_xm.c:119
acc_sensor_id_t
uint32_t acc_sensor_id_t
Type representing a sensor ID.
Definition: acc_definitions_common.h:14
acc_integration_log.h
acc_hal_a121_t::max_spi_transfer_size
uint16_t max_spi_transfer_size
Definition: acc_hal_definitions_a121.h:84
main.h
: Header for main.c file. This file contains the common defines of the application.
INTERRUPT_GPIO_Port
#define INTERRUPT_GPIO_Port
Definition: main.h:63
acc_definitions_common.h
enable_interrupts
static void enable_interrupts(void)
Definition: acc_hal_integration_stm32cube_xm.c:43
INTERRUPT_Pin
#define INTERRUPT_Pin
Definition: main.h:62