aboutsummaryrefslogtreecommitdiff
path: root/drivers/arm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/arm')
-rw-r--r--drivers/arm/i2c_master.c121
-rw-r--r--drivers/arm/i2c_master.h91
2 files changed, 98 insertions, 114 deletions
diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c
index cba5a1c67..18068d3a6 100644
--- a/drivers/arm/i2c_master.c
+++ b/drivers/arm/i2c_master.c
@@ -34,98 +34,83 @@ static uint8_t i2c_address;
34 34
35static const I2CConfig i2cconfig = { 35static const I2CConfig i2cconfig = {
36#ifdef USE_I2CV1 36#ifdef USE_I2CV1
37 I2C1_OPMODE, 37 I2C1_OPMODE,
38 I2C1_CLOCK_SPEED, 38 I2C1_CLOCK_SPEED,
39 I2C1_DUTY_CYCLE, 39 I2C1_DUTY_CYCLE,
40#else 40#else
41 STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) | 41 STM32_TIMINGR_PRESC(I2C1_TIMINGR_PRESC) | STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) | STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL), 0, 0
42 STM32_TIMINGR_SCLDEL(I2C1_TIMINGR_SCLDEL) | STM32_TIMINGR_SDADEL(I2C1_TIMINGR_SDADEL) |
43 STM32_TIMINGR_SCLH(I2C1_TIMINGR_SCLH) | STM32_TIMINGR_SCLL(I2C1_TIMINGR_SCLL),
44 0,
45 0
46#endif 42#endif
47}; 43};
48 44
49static i2c_status_t chibios_to_qmk(const msg_t* status) { 45static i2c_status_t chibios_to_qmk(const msg_t* status) {
50 switch (*status) { 46 switch (*status) {
51 case I2C_NO_ERROR: 47 case I2C_NO_ERROR:
52 return I2C_STATUS_SUCCESS; 48 return I2C_STATUS_SUCCESS;
53 case I2C_TIMEOUT: 49 case I2C_TIMEOUT:
54 return I2C_STATUS_TIMEOUT; 50 return I2C_STATUS_TIMEOUT;
55 // I2C_BUS_ERROR, I2C_ARBITRATION_LOST, I2C_ACK_FAILURE, I2C_OVERRUN, I2C_PEC_ERROR, I2C_SMB_ALERT 51 // I2C_BUS_ERROR, I2C_ARBITRATION_LOST, I2C_ACK_FAILURE, I2C_OVERRUN, I2C_PEC_ERROR, I2C_SMB_ALERT
56 default: 52 default:
57 return I2C_STATUS_ERROR; 53 return I2C_STATUS_ERROR;
58 } 54 }
59} 55}
60 56
61__attribute__ ((weak)) 57__attribute__((weak)) void i2c_init(void) {
62void i2c_init(void) 58 // Try releasing special pins for a short time
63{ 59 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT);
64 // Try releasing special pins for a short time 60 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT);
65 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_INPUT);
66 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_INPUT);
67 61
68 chThdSleepMilliseconds(10); 62 chThdSleepMilliseconds(10);
69 63
70#ifdef USE_I2CV1 64#ifdef USE_I2CV1
71 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); 65 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
72 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_STM32_ALTERNATE_OPENDRAIN); 66 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
73#else 67#else
74 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); 68 palSetPadMode(I2C1_SCL_BANK, I2C1_SCL, PAL_MODE_ALTERNATE(I2C1_SCL_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
75 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN); 69 palSetPadMode(I2C1_SDA_BANK, I2C1_SDA, PAL_MODE_ALTERNATE(I2C1_SDA_PAL_MODE) | PAL_STM32_OTYPE_OPENDRAIN);
76#endif 70#endif
77 71
78 //i2cInit(); //This is invoked by halInit() so no need to redo it. 72 // i2cInit(); //This is invoked by halInit() so no need to redo it.
79} 73}
80 74
81i2c_status_t i2c_start(uint8_t address) 75i2c_status_t i2c_start(uint8_t address) {
82{ 76 i2c_address = address;
83 i2c_address = address; 77 i2cStart(&I2C_DRIVER, &i2cconfig);
84 i2cStart(&I2C_DRIVER, &i2cconfig); 78 return I2C_STATUS_SUCCESS;
85 return I2C_STATUS_SUCCESS;
86} 79}
87 80
88i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) 81i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) {
89{ 82 i2c_address = address;
90 i2c_address = address; 83 i2cStart(&I2C_DRIVER, &i2cconfig);
91 i2cStart(&I2C_DRIVER, &i2cconfig); 84 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout));
92 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout)); 85 return chibios_to_qmk(&status);
93 return chibios_to_qmk(&status);
94} 86}
95 87
96i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) 88i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) {
97{ 89 i2c_address = address;
98 i2c_address = address; 90 i2cStart(&I2C_DRIVER, &i2cconfig);
99 i2cStart(&I2C_DRIVER, &i2cconfig); 91 msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout));
100 msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout)); 92 return chibios_to_qmk(&status);
101 return chibios_to_qmk(&status);
102} 93}
103 94
104i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) 95i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) {
105{ 96 i2c_address = devaddr;
106 i2c_address = devaddr; 97 i2cStart(&I2C_DRIVER, &i2cconfig);
107 i2cStart(&I2C_DRIVER, &i2cconfig);
108 98
109 uint8_t complete_packet[length + 1]; 99 uint8_t complete_packet[length + 1];
110 for(uint8_t i = 0; i < length; i++) 100 for (uint8_t i = 0; i < length; i++) {
111 { 101 complete_packet[i + 1] = data[i];
112 complete_packet[i+1] = data[i]; 102 }
113 } 103 complete_packet[0] = regaddr;
114 complete_packet[0] = regaddr;
115 104
116 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout)); 105 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout));
117 return chibios_to_qmk(&status); 106 return chibios_to_qmk(&status);
118} 107}
119 108
120i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) 109i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) {
121{ 110 i2c_address = devaddr;
122 i2c_address = devaddr; 111 i2cStart(&I2C_DRIVER, &i2cconfig);
123 i2cStart(&I2C_DRIVER, &i2cconfig); 112 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), &regaddr, 1, data, length, MS2ST(timeout));
124 msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), &regaddr, 1, data, length, MS2ST(timeout)); 113 return chibios_to_qmk(&status);
125 return chibios_to_qmk(&status);
126} 114}
127 115
128void i2c_stop(void) 116void i2c_stop(void) { i2cStop(&I2C_DRIVER); }
129{
130 i2cStop(&I2C_DRIVER);
131}
diff --git a/drivers/arm/i2c_master.h b/drivers/arm/i2c_master.h
index c8afa31e2..b40fa0a91 100644
--- a/drivers/arm/i2c_master.h
+++ b/drivers/arm/i2c_master.h
@@ -27,84 +27,83 @@
27#include "ch.h" 27#include "ch.h"
28#include <hal.h> 28#include <hal.h>
29 29
30
31#if defined(STM32F1XX) || defined(STM32F1xx) || defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32L0xx) || defined(STM32L1xx) 30#if defined(STM32F1XX) || defined(STM32F1xx) || defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32L0xx) || defined(STM32L1xx)
32 #define USE_I2CV1 31# define USE_I2CV1
33#endif 32#endif
34 33
35#ifdef I2C1_BANK 34#ifdef I2C1_BANK
36 #define I2C1_SCL_BANK I2C1_BANK 35# define I2C1_SCL_BANK I2C1_BANK
37 #define I2C1_SDA_BANK I2C1_BANK 36# define I2C1_SDA_BANK I2C1_BANK
38#endif 37#endif
39 38
40#ifndef I2C1_SCL_BANK 39#ifndef I2C1_SCL_BANK
41 #define I2C1_SCL_BANK GPIOB 40# define I2C1_SCL_BANK GPIOB
42#endif 41#endif
43 42
44#ifndef I2C1_SDA_BANK 43#ifndef I2C1_SDA_BANK
45 #define I2C1_SDA_BANK GPIOB 44# define I2C1_SDA_BANK GPIOB
46#endif 45#endif
47 46
48#ifndef I2C1_SCL 47#ifndef I2C1_SCL
49 #define I2C1_SCL 6 48# define I2C1_SCL 6
50#endif 49#endif
51#ifndef I2C1_SDA 50#ifndef I2C1_SDA
52 #define I2C1_SDA 7 51# define I2C1_SDA 7
53#endif 52#endif
54 53
55#ifdef USE_I2CV1 54#ifdef USE_I2CV1
56 #ifndef I2C1_OPMODE 55# ifndef I2C1_OPMODE
57 #define I2C1_OPMODE OPMODE_I2C 56# define I2C1_OPMODE OPMODE_I2C
58 #endif 57# endif
59 #ifndef I2C1_CLOCK_SPEED 58# ifndef I2C1_CLOCK_SPEED
60 #define I2C1_CLOCK_SPEED 100000 /* 400000 */ 59# define I2C1_CLOCK_SPEED 100000 /* 400000 */
61 #endif 60# endif
62 #ifndef I2C1_DUTY_CYCLE 61# ifndef I2C1_DUTY_CYCLE
63 #define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */ 62# define I2C1_DUTY_CYCLE STD_DUTY_CYCLE /* FAST_DUTY_CYCLE_2 */
64 #endif 63# endif
65#else 64#else
66 // The default PAL alternate modes are used to signal that the pins are used for I2C 65// The default PAL alternate modes are used to signal that the pins are used for I2C
67 #ifndef I2C1_SCL_PAL_MODE 66# ifndef I2C1_SCL_PAL_MODE
68 #define I2C1_SCL_PAL_MODE 4 67# define I2C1_SCL_PAL_MODE 4
69 #endif 68# endif
70 #ifndef I2C1_SDA_PAL_MODE 69# ifndef I2C1_SDA_PAL_MODE
71 #define I2C1_SDA_PAL_MODE 4 70# define I2C1_SDA_PAL_MODE 4
72 #endif 71# endif
73 72
74 // The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock 73// The default timing values below configures the I2C clock to 400khz assuming a 72Mhz clock
75 // For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html 74// For more info : https://www.st.com/en/embedded-software/stsw-stm32126.html
76 #ifndef I2C1_TIMINGR_PRESC 75# ifndef I2C1_TIMINGR_PRESC
77 #define I2C1_TIMINGR_PRESC 15U 76# define I2C1_TIMINGR_PRESC 15U
78 #endif 77# endif
79 #ifndef I2C1_TIMINGR_SCLDEL 78# ifndef I2C1_TIMINGR_SCLDEL
80 #define I2C1_TIMINGR_SCLDEL 4U 79# define I2C1_TIMINGR_SCLDEL 4U
81 #endif 80# endif
82 #ifndef I2C1_TIMINGR_SDADEL 81# ifndef I2C1_TIMINGR_SDADEL
83 #define I2C1_TIMINGR_SDADEL 2U 82# define I2C1_TIMINGR_SDADEL 2U
84 #endif 83# endif
85 #ifndef I2C1_TIMINGR_SCLH 84# ifndef I2C1_TIMINGR_SCLH
86 #define I2C1_TIMINGR_SCLH 15U 85# define I2C1_TIMINGR_SCLH 15U
87 #endif 86# endif
88 #ifndef I2C1_TIMINGR_SCLL 87# ifndef I2C1_TIMINGR_SCLL
89 #define I2C1_TIMINGR_SCLL 21U 88# define I2C1_TIMINGR_SCLL 21U
90 #endif 89# endif
91#endif 90#endif
92 91
93#ifndef I2C_DRIVER 92#ifndef I2C_DRIVER
94 #define I2C_DRIVER I2CD1 93# define I2C_DRIVER I2CD1
95#endif 94#endif
96 95
97typedef int16_t i2c_status_t; 96typedef int16_t i2c_status_t;
98 97
99#define I2C_STATUS_SUCCESS (0) 98#define I2C_STATUS_SUCCESS (0)
100#define I2C_STATUS_ERROR (-1) 99#define I2C_STATUS_ERROR (-1)
101#define I2C_STATUS_TIMEOUT (-2) 100#define I2C_STATUS_TIMEOUT (-2)
102 101
103void i2c_init(void); 102void i2c_init(void);
104i2c_status_t i2c_start(uint8_t address); 103i2c_status_t i2c_start(uint8_t address);
105i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout); 104i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout);
106i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); 105i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);
107i2c_status_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); 106i2c_status_t i2c_transmit_receive(uint8_t address, uint8_t* tx_body, uint16_t tx_length, uint8_t* rx_body, uint16_t rx_length);
108i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout); 107i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout);
109i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); 108i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);
110void i2c_stop(void); 109void i2c_stop(void);