mirror of
https://github.com/paparazzi/paparazzi.git
synced 2026-05-24 22:05:58 +08:00
[mcu] add support for I2C4 and SPI4
This commit is contained in:
@@ -105,7 +105,7 @@
|
||||
* @brief Enables the I2C subsystem.
|
||||
*/
|
||||
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__)
|
||||
#if USE_I2C1 || USE_I2C2 || USE_I2C3
|
||||
#if USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4
|
||||
#define HAL_USE_I2C TRUE
|
||||
#else
|
||||
#define HAL_USE_I2C FALSE
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#define I2C_THREAD_STACK_SIZE 512
|
||||
#endif
|
||||
|
||||
#if USE_I2C1 || USE_I2C2 || USE_I2C3
|
||||
#if USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4
|
||||
|
||||
// private I2C init structure
|
||||
struct i2c_init {
|
||||
@@ -177,7 +177,7 @@ static void handle_i2c_thd(struct i2c_periph *p)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* USE_I2C1 || USE_I2C2 || USE_I2C3 */
|
||||
#endif /* USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4 */
|
||||
|
||||
#if USE_I2C1
|
||||
// I2C1 config
|
||||
@@ -342,6 +342,61 @@ static void thd_i2c3(void *arg)
|
||||
}
|
||||
#endif /* USE_I2C3 */
|
||||
|
||||
#if USE_I2C4
|
||||
// I2C4 config
|
||||
PRINT_CONFIG_VAR(I2C4_CLOCK_SPEED)
|
||||
static SEMAPHORE_DECL(i2c4_sem, 0);
|
||||
static I2CConfig i2cfg4 = I2C4_CFG_DEF;
|
||||
#if defined STM32F7
|
||||
// We need a special buffer for DMA operations
|
||||
static IN_DMA_SECTION(uint8_t i2c4_dma_buf[I2C_BUF_LEN]);
|
||||
static struct i2c_init i2c4_init_s = {
|
||||
.sem = &i2c4_sem,
|
||||
.cfg = &i2cfg4,
|
||||
.dma_buf = i2c4_dma_buf
|
||||
};
|
||||
#else
|
||||
static struct i2c_init i2c4_init_s = {
|
||||
.sem = &i2c4_sem,
|
||||
.cfg = &i2cfg4
|
||||
};
|
||||
#endif
|
||||
// Errors
|
||||
struct i2c_errors i2c4_errors;
|
||||
// Thread
|
||||
static __attribute__((noreturn)) void thd_i2c4(void *arg);
|
||||
static THD_WORKING_AREA(wa_thd_i2c4, 128);
|
||||
|
||||
/*
|
||||
* I2C4 init
|
||||
*/
|
||||
void i2c4_hw_init(void)
|
||||
{
|
||||
i2cStart(&I2CD4, &i2cfg4);
|
||||
i2c4.reg_addr = &I2CD4;
|
||||
i2c4.init_struct = NULL;
|
||||
i2c4.errors = &i2c4_errors;
|
||||
i2c4.init_struct = &i2c4_init_s;
|
||||
// Create thread
|
||||
chThdCreateStatic(wa_thd_i2c4, sizeof(wa_thd_i2c4),
|
||||
NORMALPRIO + 1, thd_i2c4, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* I2C4 thread
|
||||
*
|
||||
*/
|
||||
static void thd_i2c4(void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
chRegSetThreadName("i2c4");
|
||||
|
||||
while (TRUE) {
|
||||
handle_i2c_thd(&i2c4);
|
||||
}
|
||||
}
|
||||
#endif /* USE_I2C4 */
|
||||
|
||||
|
||||
/**
|
||||
* i2c_event() function
|
||||
@@ -377,7 +432,7 @@ void i2c_setbitrate(struct i2c_periph *p __attribute__((unused)), int bitrate __
|
||||
*/
|
||||
bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
|
||||
{
|
||||
#if USE_I2C1 || USE_I2C2 || USE_I2C3
|
||||
#if USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4
|
||||
// sys lock
|
||||
chSysLock();
|
||||
uint8_t temp;
|
||||
@@ -406,7 +461,7 @@ bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
|
||||
(void)p;
|
||||
(void)t;
|
||||
return FALSE;
|
||||
#endif /* USE_I2C1 || USE_I2C2 || USE_I2C3 */
|
||||
#endif /* USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,4 +45,8 @@ extern void i2c2_hw_init(void);
|
||||
extern void i2c3_hw_init(void);
|
||||
#endif /* USE_I2C3 */
|
||||
|
||||
#if USE_I2C4
|
||||
extern void i2c4_hw_init(void);
|
||||
#endif /* USE_I2C4 */
|
||||
|
||||
#endif /* I2C_HW_H */
|
||||
|
||||
@@ -167,10 +167,12 @@ static inline uint16_t spi_resolve_slave_pin(uint8_t slave)
|
||||
static inline uint16_t spi_resolve_CR1(struct spi_transaction *t __attribute__((unused)))
|
||||
{
|
||||
uint16_t CR1 = 0;
|
||||
#if defined(STM32F1) || defined(STM32F4) || defined(STM32F7)
|
||||
#if defined(STM32F1) || defined(STM32F4)
|
||||
if (t->dss == SPIDss16bit) {
|
||||
CR1 |= SPI_CR1_DFF;
|
||||
CR1 |= SPI_CR1_DFF; // FIXME for F7
|
||||
}
|
||||
#endif
|
||||
#if defined(STM32F1) || defined(STM32F4) || defined(STM32F7)
|
||||
if (t->bitorder == SPILSBFirst) {
|
||||
CR1 |= SPI_CR1_LSBFIRST;
|
||||
}
|
||||
@@ -443,6 +445,45 @@ void spi3_arch_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USE_SPI4
|
||||
static SEMAPHORE_DECL(spi4_sem, 0);
|
||||
#if defined STM32F7
|
||||
// We need a special buffer for DMA operations
|
||||
static IN_DMA_SECTION(uint8_t spi4_dma_buf_out[SPI_DMA_BUF_LEN]);
|
||||
static IN_DMA_SECTION(uint8_t spi4_dma_buf_in[SPI_DMA_BUF_LEN]);
|
||||
static struct spi_init spi4_init_s = {
|
||||
.sem = &spi4_sem,
|
||||
.dma_buf_out = spi4_dma_buf_out,
|
||||
.dma_buf_in = spi4_dma_buf_in
|
||||
};
|
||||
#else
|
||||
static struct spi_init spi4_init_s = {
|
||||
.sem = &spi4_sem,
|
||||
};
|
||||
#endif
|
||||
|
||||
static __attribute__((noreturn)) void thd_spi4(void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
chRegSetThreadName("spi4");
|
||||
|
||||
while (TRUE) {
|
||||
handle_spi_thd(&spi4);
|
||||
}
|
||||
}
|
||||
|
||||
static THD_WORKING_AREA(wa_thd_spi4, 256);
|
||||
|
||||
void spi4_arch_init(void)
|
||||
{
|
||||
spi4.reg_addr = &SPID4;
|
||||
spi4.init_struct = &spi4_init_s;
|
||||
// Create thread
|
||||
chThdCreateStatic(wa_thd_spi4, sizeof(wa_thd_spi4),
|
||||
NORMALPRIO + 1, thd_spi4, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Submit SPI transaction
|
||||
|
||||
+7
-1
@@ -43,7 +43,7 @@
|
||||
#define USING_UART 1
|
||||
#include "mcu_periph/uart.h"
|
||||
#endif
|
||||
#if USE_I2C0 || USE_I2C1 || USE_I2C2 || USE_I2C3
|
||||
#if USE_I2C0 || USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4
|
||||
#define USING_I2C 1
|
||||
#include "mcu_periph/i2c.h"
|
||||
#endif
|
||||
@@ -173,6 +173,9 @@ void mcu_init(void)
|
||||
#ifdef USE_I2C3
|
||||
i2c3_init();
|
||||
#endif
|
||||
#ifdef USE_I2C4
|
||||
i2c4_init();
|
||||
#endif
|
||||
#if USE_ADC
|
||||
adc_init();
|
||||
#endif
|
||||
@@ -194,6 +197,9 @@ void mcu_init(void)
|
||||
#endif
|
||||
#if USE_SPI3
|
||||
spi3_init();
|
||||
#endif
|
||||
#if USE_SPI4
|
||||
spi4_init();
|
||||
#endif
|
||||
spi_init_slaves();
|
||||
#endif // SPI_MASTER
|
||||
|
||||
@@ -206,6 +206,49 @@ static void send_i2c3_err(struct transport_tx *trans, struct link_device *dev)
|
||||
|
||||
#endif /* USE_I2C3 */
|
||||
|
||||
#if USE_I2C4
|
||||
|
||||
struct i2c_periph i2c4;
|
||||
|
||||
void i2c4_init(void)
|
||||
{
|
||||
i2c_init(&i2c4);
|
||||
i2c4_hw_init();
|
||||
}
|
||||
|
||||
#if PERIODIC_TELEMETRY
|
||||
static void send_i2c4_err(struct transport_tx *trans, struct link_device *dev)
|
||||
{
|
||||
uint16_t i2c4_wd_reset_cnt = i2c4.errors->wd_reset_cnt;
|
||||
uint16_t i2c4_queue_full_cnt = i2c4.errors->queue_full_cnt;
|
||||
uint16_t i2c4_ack_fail_cnt = i2c4.errors->ack_fail_cnt;
|
||||
uint16_t i2c4_miss_start_stop_cnt = i2c4.errors->miss_start_stop_cnt;
|
||||
uint16_t i2c4_arb_lost_cnt = i2c4.errors->arb_lost_cnt;
|
||||
uint16_t i2c4_over_under_cnt = i2c4.errors->over_under_cnt;
|
||||
uint16_t i2c4_pec_recep_cnt = i2c4.errors->pec_recep_cnt;
|
||||
uint16_t i2c4_timeout_tlow_cnt = i2c4.errors->timeout_tlow_cnt;
|
||||
uint16_t i2c4_smbus_alert_cnt = i2c4.errors->smbus_alert_cnt;
|
||||
uint16_t i2c4_unexpected_event_cnt = i2c4.errors->unexpected_event_cnt;
|
||||
uint32_t i2c4_last_unexpected_event = i2c4.errors->last_unexpected_event;
|
||||
uint8_t _bus4 = 4;
|
||||
pprz_msg_send_I2C_ERRORS(trans, dev, AC_ID,
|
||||
&i2c4_wd_reset_cnt,
|
||||
&i2c4_queue_full_cnt,
|
||||
&i2c4_ack_fail_cnt,
|
||||
&i2c4_miss_start_stop_cnt,
|
||||
&i2c4_arb_lost_cnt,
|
||||
&i2c4_over_under_cnt,
|
||||
&i2c4_pec_recep_cnt,
|
||||
&i2c4_timeout_tlow_cnt,
|
||||
&i2c4_smbus_alert_cnt,
|
||||
&i2c4_unexpected_event_cnt,
|
||||
&i2c4_last_unexpected_event,
|
||||
&_bus4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* USE_I2C4 */
|
||||
|
||||
#if PERIODIC_TELEMETRY
|
||||
static void send_i2c_err(struct transport_tx *trans __attribute__((unused)),
|
||||
struct link_device *dev __attribute__((unused)))
|
||||
@@ -230,6 +273,11 @@ static void send_i2c_err(struct transport_tx *trans __attribute__((unused)),
|
||||
case 3:
|
||||
#if USE_I2C3
|
||||
send_i2c3_err(trans, dev);
|
||||
#endif
|
||||
break;
|
||||
case 4:
|
||||
#if USE_I2C4
|
||||
send_i2c4_err(trans, dev);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -215,6 +215,14 @@ extern void i2c3_init(void);
|
||||
#endif /* USE_I2C3 */
|
||||
|
||||
|
||||
#if USE_I2C4
|
||||
|
||||
extern struct i2c_periph i2c4;
|
||||
extern void i2c4_init(void);
|
||||
|
||||
#endif /* USE_I2C4 */
|
||||
|
||||
|
||||
/** Initialize I2C peripheral */
|
||||
extern void i2c_init(struct i2c_periph *p);
|
||||
|
||||
|
||||
@@ -75,6 +75,17 @@ void spi3_init(void)
|
||||
#endif // USE_SPI3
|
||||
|
||||
|
||||
#if USE_SPI4
|
||||
struct spi_periph spi4;
|
||||
|
||||
void spi4_init(void)
|
||||
{
|
||||
spi_init(&spi4);
|
||||
spi4_arch_init();
|
||||
}
|
||||
#endif // USE_SPI4
|
||||
|
||||
|
||||
void spi_init(struct spi_periph *p)
|
||||
{
|
||||
p->trans_insert_idx = 0;
|
||||
|
||||
@@ -241,6 +241,18 @@ extern void spi3_arch_init(void);
|
||||
|
||||
#endif // USE_SPI3
|
||||
|
||||
#if USE_SPI4
|
||||
|
||||
extern struct spi_periph spi4;
|
||||
extern void spi4_init(void);
|
||||
|
||||
/** Architecture dependent SPI4 initialization.
|
||||
* Must be implemented by underlying architecture
|
||||
*/
|
||||
extern void spi4_arch_init(void);
|
||||
|
||||
#endif // USE_SPI4
|
||||
|
||||
/** Initialize a spi peripheral.
|
||||
* @param p spi peripheral to be configured
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user