mirror of https://github.com/rusefi/bldc.git
commit
fcb7aaa93f
1
Makefile
1
Makefile
|
@ -155,6 +155,7 @@ CSRC = $(STARTUPSRC) \
|
||||||
confgenerator.c \
|
confgenerator.c \
|
||||||
timer.c \
|
timer.c \
|
||||||
i2c_bb.c \
|
i2c_bb.c \
|
||||||
|
spi_bb.c \
|
||||||
virtual_motor.c \
|
virtual_motor.c \
|
||||||
shutdown.c \
|
shutdown.c \
|
||||||
mempools.c \
|
mempools.c \
|
||||||
|
|
|
@ -201,6 +201,16 @@
|
||||||
#define HW_SPI_PORT_MISO GPIOA
|
#define HW_SPI_PORT_MISO GPIOA
|
||||||
#define HW_SPI_PIN_MISO 6
|
#define HW_SPI_PIN_MISO 6
|
||||||
|
|
||||||
|
//BMI160 SPI pins
|
||||||
|
#define BMI160_SPI_PORT_NSS GPIOC
|
||||||
|
#define BMI160_SPI_PIN_NSS 9
|
||||||
|
#define BMI160_SPI_PORT_SCK GPIOC
|
||||||
|
#define BMI160_SPI_PIN_SCK 10
|
||||||
|
#define BMI160_SPI_PORT_MOSI GPIOC
|
||||||
|
#define BMI160_SPI_PIN_MOSI 12
|
||||||
|
#define BMI160_SPI_PORT_MISO GPIOC
|
||||||
|
#define BMI160_SPI_PIN_MISO 11
|
||||||
|
|
||||||
// Measurement macros
|
// Measurement macros
|
||||||
#define ADC_V_L1 ADC_Value[ADC_IND_SENS1]
|
#define ADC_V_L1 ADC_Value[ADC_IND_SENS1]
|
||||||
#define ADC_V_L2 ADC_Value[ADC_IND_SENS2]
|
#define ADC_V_L2 ADC_Value[ADC_IND_SENS2]
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "i2c_bb.h"
|
#include "i2c_bb.h"
|
||||||
|
#include "spi_bb.h"
|
||||||
#include "bmi160.h"
|
#include "bmi160.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
96
imu/imu.c
96
imu/imu.c
|
@ -37,6 +37,7 @@ static ATTITUDE_INFO m_att;
|
||||||
static float m_accel[3], m_gyro[3], m_mag[3];
|
static float m_accel[3], m_gyro[3], m_mag[3];
|
||||||
static stkalign_t m_thd_work_area[THD_WORKING_AREA_SIZE(2048) / sizeof(stkalign_t)];
|
static stkalign_t m_thd_work_area[THD_WORKING_AREA_SIZE(2048) / sizeof(stkalign_t)];
|
||||||
static i2c_bb_state m_i2c_bb;
|
static i2c_bb_state m_i2c_bb;
|
||||||
|
static spi_bb_state m_spi_bb;
|
||||||
static ICM20948_STATE m_icm20948_state;
|
static ICM20948_STATE m_icm20948_state;
|
||||||
static BMI_STATE m_bmi_state;
|
static BMI_STATE m_bmi_state;
|
||||||
static imu_config m_settings;
|
static imu_config m_settings;
|
||||||
|
@ -50,6 +51,8 @@ static void terminal_gyro_info(int argc, const char **argv);
|
||||||
static void rotate(float *input, float *rotation, float *output);
|
static void rotate(float *input, float *rotation, float *output);
|
||||||
int8_t user_i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
int8_t user_i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
||||||
int8_t user_i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
int8_t user_i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
||||||
|
int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
||||||
|
int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len);
|
||||||
|
|
||||||
void imu_init(imu_config *set) {
|
void imu_init(imu_config *set) {
|
||||||
m_settings = *set;
|
m_settings = *set;
|
||||||
|
@ -80,7 +83,7 @@ void imu_init(imu_config *set) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BMI160_SDA_GPIO
|
#ifdef BMI160_SDA_GPIO
|
||||||
imu_init_bmi160(BMI160_SDA_GPIO, BMI160_SDA_PIN,
|
imu_init_bmi160_i2c(BMI160_SDA_GPIO, BMI160_SDA_PIN,
|
||||||
BMI160_SCL_GPIO, BMI160_SCL_PIN);
|
BMI160_SCL_GPIO, BMI160_SCL_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -88,6 +91,14 @@ void imu_init(imu_config *set) {
|
||||||
imu_init_lsm6ds3(LSM6DS3_SDA_GPIO, LSM6DS3_SDA_PIN,
|
imu_init_lsm6ds3(LSM6DS3_SDA_GPIO, LSM6DS3_SDA_PIN,
|
||||||
LSM6DS3_SCL_GPIO, LSM6DS3_SCL_PIN);
|
LSM6DS3_SCL_GPIO, LSM6DS3_SCL_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BMI160_SPI_PORT_NSS
|
||||||
|
imu_init_bmi160_spi(
|
||||||
|
BMI160_SPI_PORT_NSS, BMI160_SPI_PIN_NSS,
|
||||||
|
BMI160_SPI_PORT_SCK, BMI160_SPI_PIN_SCK,
|
||||||
|
BMI160_SPI_PORT_MOSI, BMI160_SPI_PIN_MOSI,
|
||||||
|
BMI160_SPI_PORT_MISO, BMI160_SPI_PIN_MISO);
|
||||||
|
#endif
|
||||||
} else if (set->type == IMU_TYPE_EXTERNAL_MPU9X50) {
|
} else if (set->type == IMU_TYPE_EXTERNAL_MPU9X50) {
|
||||||
imu_init_mpu9x50(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
imu_init_mpu9x50(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
||||||
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
|
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
|
||||||
|
@ -95,11 +106,14 @@ void imu_init(imu_config *set) {
|
||||||
imu_init_icm20948(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
imu_init_icm20948(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
||||||
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN, 0);
|
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN, 0);
|
||||||
} else if (set->type == IMU_TYPE_EXTERNAL_BMI160) {
|
} else if (set->type == IMU_TYPE_EXTERNAL_BMI160) {
|
||||||
imu_init_bmi160(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
imu_init_bmi160_i2c(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
||||||
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
|
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
|
||||||
} else if(set->type == IMU_TYPE_EXTERNAL_LSM6DS3) {
|
} else if(set->type == IMU_TYPE_EXTERNAL_LSM6DS3) {
|
||||||
imu_init_lsm6ds3(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
imu_init_lsm6ds3(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
||||||
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
|
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
|
||||||
|
} else if (set->type == IMU_TYPE_EXTERNAL_BMI160) {
|
||||||
|
imu_init_bmi160_i2c(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
|
||||||
|
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
terminal_register_command_callback(
|
terminal_register_command_callback(
|
||||||
|
@ -139,7 +153,7 @@ void imu_init_icm20948(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
icm20948_set_read_callback(&m_icm20948_state, imu_read_callback);
|
icm20948_set_read_callback(&m_icm20948_state, imu_read_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imu_init_bmi160(stm32_gpio_t *sda_gpio, int sda_pin,
|
void imu_init_bmi160_i2c(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
stm32_gpio_t *scl_gpio, int scl_pin) {
|
stm32_gpio_t *scl_gpio, int scl_pin) {
|
||||||
imu_stop();
|
imu_stop();
|
||||||
|
|
||||||
|
@ -158,6 +172,32 @@ void imu_init_bmi160(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
bmi160_wrapper_set_read_callback(&m_bmi_state, imu_read_callback);
|
bmi160_wrapper_set_read_callback(&m_bmi_state, imu_read_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void imu_init_bmi160_spi(stm32_gpio_t *nss_gpio, int nss_pin,
|
||||||
|
stm32_gpio_t *sck_gpio, int sck_pin, stm32_gpio_t *mosi_gpio, int mosi_pin,
|
||||||
|
stm32_gpio_t *miso_gpio, int miso_pin) {
|
||||||
|
imu_stop();
|
||||||
|
|
||||||
|
m_spi_bb.nss_gpio = nss_gpio;
|
||||||
|
m_spi_bb.nss_pin = nss_pin;
|
||||||
|
m_spi_bb.sck_gpio = sck_gpio;
|
||||||
|
m_spi_bb.sck_pin = sck_pin;
|
||||||
|
m_spi_bb.mosi_gpio = mosi_gpio;
|
||||||
|
m_spi_bb.mosi_pin = mosi_pin;
|
||||||
|
m_spi_bb.miso_gpio = miso_gpio;
|
||||||
|
m_spi_bb.miso_pin = miso_pin;
|
||||||
|
|
||||||
|
spi_bb_init(&m_spi_bb);
|
||||||
|
|
||||||
|
m_bmi_state.sensor.id = 0;
|
||||||
|
m_bmi_state.sensor.interface = BMI160_SPI_INTF;
|
||||||
|
m_bmi_state.sensor.read = user_spi_read;
|
||||||
|
m_bmi_state.sensor.write = user_spi_write;
|
||||||
|
|
||||||
|
bmi160_wrapper_init(&m_bmi_state, m_thd_work_area, sizeof(m_thd_work_area));
|
||||||
|
|
||||||
|
bmi160_wrapper_set_read_callback(&m_bmi_state, imu_read_callback);
|
||||||
|
}
|
||||||
|
|
||||||
void imu_init_lsm6ds3(stm32_gpio_t *sda_gpio, int sda_pin,
|
void imu_init_lsm6ds3(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
stm32_gpio_t *scl_gpio, int scl_pin) {
|
stm32_gpio_t *scl_gpio, int scl_pin) {
|
||||||
|
|
||||||
|
@ -511,3 +551,53 @@ int8_t user_i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_
|
||||||
memcpy(txbuf + 1, data, len);
|
memcpy(txbuf + 1, data, len);
|
||||||
return i2c_bb_tx_rx(&m_i2c_bb, dev_addr, txbuf, len + 1, 0, 0) ? BMI160_OK : BMI160_E_COM_FAIL;
|
return i2c_bb_tx_rx(&m_i2c_bb, dev_addr, txbuf, len + 1, 0, 0) ? BMI160_OK : BMI160_E_COM_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t user_spi_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len) {
|
||||||
|
//commands_printf("user spi reading");
|
||||||
|
|
||||||
|
int8_t rslt = BMI160_OK; // Return 0 for Success, non-zero for failure
|
||||||
|
|
||||||
|
//reg_addr = BMI160_CHIP_ID_ADDR;
|
||||||
|
//len = 1;
|
||||||
|
reg_addr = (reg_addr | BMI160_SPI_RD_MASK);
|
||||||
|
|
||||||
|
chThdSleepMicroseconds(200); // #FIXME Wont work without this- Why?
|
||||||
|
|
||||||
|
|
||||||
|
chMtxLock(&m_spi_bb.mutex);
|
||||||
|
spi_begin(&m_spi_bb);
|
||||||
|
//spi_exchange_8(reg_addr);
|
||||||
|
spi_exchange_8(&m_spi_bb, reg_addr);
|
||||||
|
spi_delay();
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
//data[i] = spi_exchange_8(0);
|
||||||
|
data[i] = spi_exchange_8(&m_spi_bb, 0);;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_end(&m_spi_bb);
|
||||||
|
chMtxUnlock(&m_spi_bb.mutex);
|
||||||
|
return rslt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t len) {
|
||||||
|
|
||||||
|
int8_t rslt = BMI160_OK; /* Return 0 for Success, non-zero for failure */
|
||||||
|
chMtxLock(&m_spi_bb.mutex);
|
||||||
|
spi_begin(&m_spi_bb);
|
||||||
|
reg_addr = (reg_addr & BMI160_SPI_WR_MASK);
|
||||||
|
//spi_exchange_8(reg_addr);
|
||||||
|
spi_exchange_8(&m_spi_bb, reg_addr);
|
||||||
|
spi_delay();
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
|
||||||
|
//spi_exchange_8(*data);
|
||||||
|
spi_exchange_8(&m_spi_bb, *data);
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
spi_end(&m_spi_bb);
|
||||||
|
chMtxUnlock(&m_spi_bb.mutex);
|
||||||
|
|
||||||
|
return rslt;
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "ch.h"
|
#include "ch.h"
|
||||||
#include "hal.h"
|
#include "hal.h"
|
||||||
#include "i2c_bb.h"
|
#include "i2c_bb.h"
|
||||||
|
#include "spi_bb.h"
|
||||||
|
|
||||||
void imu_init(imu_config *set);
|
void imu_init(imu_config *set);
|
||||||
i2c_bb_state *imu_get_i2c(void);
|
i2c_bb_state *imu_get_i2c(void);
|
||||||
|
@ -30,10 +31,15 @@ void imu_init_mpu9x50(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
stm32_gpio_t *scl_gpio, int scl_pin);
|
stm32_gpio_t *scl_gpio, int scl_pin);
|
||||||
void imu_init_icm20948(stm32_gpio_t *sda_gpio, int sda_pin,
|
void imu_init_icm20948(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
stm32_gpio_t *scl_gpio, int scl_pin, int ad0_val);
|
stm32_gpio_t *scl_gpio, int scl_pin, int ad0_val);
|
||||||
void imu_init_bmi160(stm32_gpio_t *sda_gpio, int sda_pin,
|
void imu_init_bmi160_i2c(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
stm32_gpio_t *scl_gpio, int scl_pin);
|
stm32_gpio_t *scl_gpio, int scl_pin);
|
||||||
void imu_init_lsm6ds3(stm32_gpio_t *sda_gpio, int sda_pin,
|
void imu_init_lsm6ds3(stm32_gpio_t *sda_gpio, int sda_pin,
|
||||||
stm32_gpio_t *scl_gpio, int scl_pin);
|
stm32_gpio_t *scl_gpio, int scl_pin);
|
||||||
|
void imu_init_bmi160_spi(
|
||||||
|
stm32_gpio_t *nss_gpio, int nss_pin,
|
||||||
|
stm32_gpio_t *sck_gpio, int sck_pin,
|
||||||
|
stm32_gpio_t *mosi_gpio, int mosi_pin,
|
||||||
|
stm32_gpio_t *miso_gpio, int miso_pin);
|
||||||
void imu_stop(void);
|
void imu_stop(void);
|
||||||
bool imu_startup_done(void);
|
bool imu_startup_done(void);
|
||||||
float imu_get_roll(void);
|
float imu_get_roll(void);
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 Benjamin Vedder benjamin@vedder.se
|
||||||
|
|
||||||
|
This file is part of the VESC firmware.
|
||||||
|
|
||||||
|
The VESC firmware is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
The VESC firmware is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "spi_bb.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
// Software SPI
|
||||||
|
|
||||||
|
void spi_bb_init(spi_bb_state *s) {
|
||||||
|
chMtxObjectInit(&s->mutex);
|
||||||
|
|
||||||
|
palSetPadMode(s->miso_gpio, s->miso_pin, PAL_MODE_INPUT_PULLUP);
|
||||||
|
palSetPadMode(s->sck_gpio, s->sck_pin, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
|
||||||
|
palSetPadMode(s->nss_gpio, s->nss_pin, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
|
||||||
|
palSetPadMode(s->mosi_gpio, s->mosi_pin, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST);
|
||||||
|
palSetPad(s->mosi_gpio, s->mosi_pin);
|
||||||
|
palSetPad(s->nss_gpio, s->nss_pin);
|
||||||
|
|
||||||
|
s->has_started = false;
|
||||||
|
s->has_error = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t spi_exchange_8(spi_bb_state *s, uint8_t x) {
|
||||||
|
uint8_t rx;
|
||||||
|
spi_transfer_8(s ,&rx, &x, 1);
|
||||||
|
return rx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_transfer_8(spi_bb_state *s, uint8_t *in_buf, const uint8_t *out_buf, int length) {
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
uint8_t send = out_buf ? out_buf[i] : 0xFF;
|
||||||
|
uint8_t receive = 0;
|
||||||
|
|
||||||
|
for (int bit = 0; bit < 8; bit++) {
|
||||||
|
palWritePad(s->mosi_gpio, s->mosi_pin, send >> 7);
|
||||||
|
send <<= 1;
|
||||||
|
|
||||||
|
palSetPad(s->sck_gpio, s->sck_pin);
|
||||||
|
spi_delay();
|
||||||
|
|
||||||
|
int samples = 0;
|
||||||
|
samples += palReadPad(s->miso_gpio, s->miso_pin);
|
||||||
|
__NOP();
|
||||||
|
samples += palReadPad(s->miso_gpio, s->miso_pin);
|
||||||
|
__NOP();
|
||||||
|
samples += palReadPad(s->miso_gpio, s->miso_pin);
|
||||||
|
__NOP();
|
||||||
|
samples += palReadPad(s->miso_gpio, s->miso_pin);
|
||||||
|
__NOP();
|
||||||
|
samples += palReadPad(s->miso_gpio, s->miso_pin);
|
||||||
|
|
||||||
|
palClearPad(s->sck_gpio, s->sck_pin);
|
||||||
|
|
||||||
|
// does 5 samples of each pad read, to minimize noise
|
||||||
|
receive <<= 1;
|
||||||
|
if (samples > 2) {
|
||||||
|
receive |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
spi_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (in_buf) {
|
||||||
|
in_buf[i] = receive;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_begin(spi_bb_state *s) {
|
||||||
|
spi_delay();
|
||||||
|
palClearPad(s->nss_gpio, s->nss_pin);
|
||||||
|
spi_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_end(spi_bb_state *s) {
|
||||||
|
spi_delay();
|
||||||
|
palSetPad(s->nss_gpio, s->nss_pin);
|
||||||
|
spi_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
void spi_delay(void) {
|
||||||
|
for (volatile int i = 0; i < 40; i++) {
|
||||||
|
__NOP();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
Copyright 2019 Benjamin Vedder benjamin@vedder.se
|
||||||
|
|
||||||
|
This file is part of the VESC firmware.
|
||||||
|
|
||||||
|
The VESC firmware is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
The VESC firmware is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SPI_BB_H_
|
||||||
|
#define SPI_BB_H_
|
||||||
|
|
||||||
|
#include "ch.h"
|
||||||
|
#include "hal.h"
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
stm32_gpio_t *nss_gpio;
|
||||||
|
int nss_pin;
|
||||||
|
stm32_gpio_t *sck_gpio;
|
||||||
|
int sck_pin;
|
||||||
|
stm32_gpio_t *mosi_gpio;
|
||||||
|
int mosi_pin;
|
||||||
|
stm32_gpio_t *miso_gpio;
|
||||||
|
int miso_pin;
|
||||||
|
bool has_started;
|
||||||
|
bool has_error;
|
||||||
|
mutex_t mutex;
|
||||||
|
} spi_bb_state;
|
||||||
|
|
||||||
|
void spi_bb_init(spi_bb_state *s);
|
||||||
|
uint8_t spi_exchange_8(spi_bb_state *s, uint8_t x);
|
||||||
|
void spi_transfer_8(spi_bb_state *s, uint8_t *in_buf, const uint8_t *out_buf, int length);
|
||||||
|
|
||||||
|
void spi_begin(spi_bb_state *s);
|
||||||
|
void spi_end(spi_bb_state *s);
|
||||||
|
void spi_delay(void);
|
||||||
|
|
||||||
|
#endif /* SPI_BB_H_ */
|
Loading…
Reference in New Issue