[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. * @brief Enables the I2C subsystem.
*/ */
#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) #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 #define HAL_USE_I2C TRUE
#else #else
#define HAL_USE_I2C FALSE #define HAL_USE_I2C FALSE
+59 -4
View File
@@ -46,7 +46,7 @@
#define I2C_THREAD_STACK_SIZE 512 #define I2C_THREAD_STACK_SIZE 512
#endif #endif
#if USE_I2C1 || USE_I2C2 || USE_I2C3 #if USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4
// private I2C init structure // private I2C init structure
struct i2c_init { struct i2c_init {
@@ -177,7 +177,7 @@ static void handle_i2c_thd(struct i2c_periph *p)
break; break;
} }
} }
#endif /* USE_I2C1 || USE_I2C2 || USE_I2C3 */ #endif /* USE_I2C1 || USE_I2C2 || USE_I2C3 || USE_I2C4 */
#if USE_I2C1 #if USE_I2C1
// I2C1 config // I2C1 config
@@ -342,6 +342,61 @@ static void thd_i2c3(void *arg)
} }
#endif /* USE_I2C3 */ #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 * 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) 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 // sys lock
chSysLock(); chSysLock();
uint8_t temp; uint8_t temp;
@@ -406,7 +461,7 @@ bool i2c_submit(struct i2c_periph *p, struct i2c_transaction *t)
(void)p; (void)p;
(void)t; (void)t;
return FALSE; 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); extern void i2c3_hw_init(void);
#endif /* USE_I2C3 */ #endif /* USE_I2C3 */
#if USE_I2C4
extern void i2c4_hw_init(void);
#endif /* USE_I2C4 */
#endif /* I2C_HW_H */ #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))) static inline uint16_t spi_resolve_CR1(struct spi_transaction *t __attribute__((unused)))
{ {
uint16_t CR1 = 0; uint16_t CR1 = 0;
#if defined(STM32F1) || defined(STM32F4) || defined(STM32F7) #if defined(STM32F1) || defined(STM32F4)
if (t->dss == SPIDss16bit) { 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) { if (t->bitorder == SPILSBFirst) {
CR1 |= SPI_CR1_LSBFIRST; CR1 |= SPI_CR1_LSBFIRST;
} }
@@ -443,6 +445,45 @@ void spi3_arch_init(void)
} }
#endif #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 * Submit SPI transaction
+7 -1
View File
@@ -43,7 +43,7 @@
#define USING_UART 1 #define USING_UART 1
#include "mcu_periph/uart.h" #include "mcu_periph/uart.h"
#endif #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 #define USING_I2C 1
#include "mcu_periph/i2c.h" #include "mcu_periph/i2c.h"
#endif #endif
@@ -173,6 +173,9 @@ void mcu_init(void)
#ifdef USE_I2C3 #ifdef USE_I2C3
i2c3_init(); i2c3_init();
#endif #endif
#ifdef USE_I2C4
i2c4_init();
#endif
#if USE_ADC #if USE_ADC
adc_init(); adc_init();
#endif #endif
@@ -194,6 +197,9 @@ void mcu_init(void)
#endif #endif
#if USE_SPI3 #if USE_SPI3
spi3_init(); spi3_init();
#endif
#if USE_SPI4
spi4_init();
#endif #endif
spi_init_slaves(); spi_init_slaves();
#endif // SPI_MASTER #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 */ #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 #if PERIODIC_TELEMETRY
static void send_i2c_err(struct transport_tx *trans __attribute__((unused)), static void send_i2c_err(struct transport_tx *trans __attribute__((unused)),
struct link_device *dev __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: case 3:
#if USE_I2C3 #if USE_I2C3
send_i2c3_err(trans, dev); send_i2c3_err(trans, dev);
#endif
break;
case 4:
#if USE_I2C4
send_i2c4_err(trans, dev);
#endif #endif
break; break;
default: default:
+8
View File
@@ -215,6 +215,14 @@ extern void i2c3_init(void);
#endif /* USE_I2C3 */ #endif /* USE_I2C3 */
#if USE_I2C4
extern struct i2c_periph i2c4;
extern void i2c4_init(void);
#endif /* USE_I2C4 */
/** Initialize I2C peripheral */ /** Initialize I2C peripheral */
extern void i2c_init(struct i2c_periph *p); extern void i2c_init(struct i2c_periph *p);
+11
View File
@@ -75,6 +75,17 @@ void spi3_init(void)
#endif // USE_SPI3 #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) void spi_init(struct spi_periph *p)
{ {
p->trans_insert_idx = 0; p->trans_insert_idx = 0;
+12
View File
@@ -241,6 +241,18 @@ extern void spi3_arch_init(void);
#endif // USE_SPI3 #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. /** Initialize a spi peripheral.
* @param p spi peripheral to be configured * @param p spi peripheral to be configured
*/ */