[mcu] add support for I2C4 and SPI4

This commit is contained in:
Gautier Hattenberger
2019-05-03 23:05:16 +02:00
parent d23ed71ede
commit db991f402f
9 changed files with 193 additions and 8 deletions
+1 -1
View File
@@ -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
+59 -4
View File
@@ -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 */
+43 -2
View File
@@ -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
View File
@@ -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
+48
View File
@@ -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:
+8
View File
@@ -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);
+11
View File
@@ -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;
+12
View File
@@ -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
*/