diff options
Diffstat (limited to 'drivers/arm')
| -rw-r--r-- | drivers/arm/i2c_master.c | 121 | ||||
| -rw-r--r-- | drivers/arm/i2c_master.h | 91 |
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 | ||
| 35 | static const I2CConfig i2cconfig = { | 35 | static 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 | ||
| 49 | static i2c_status_t chibios_to_qmk(const msg_t* status) { | 45 | static 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) { |
| 62 | void 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 | ||
| 81 | i2c_status_t i2c_start(uint8_t address) | 75 | i2c_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 | ||
| 88 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) | 81 | i2c_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 | ||
| 96 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) | 88 | i2c_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 | ||
| 104 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) | 95 | i2c_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 | ||
| 120 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) | 109 | i2c_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), ®addr, 1, data, length, MS2ST(timeout)); |
| 124 | msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), ®addr, 1, data, length, MS2ST(timeout)); | 113 | return chibios_to_qmk(&status); |
| 125 | return chibios_to_qmk(&status); | ||
| 126 | } | 114 | } |
| 127 | 115 | ||
| 128 | void i2c_stop(void) | 116 | void 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 | ||
| 97 | typedef int16_t i2c_status_t; | 96 | typedef 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 | ||
| 103 | void i2c_init(void); | 102 | void i2c_init(void); |
| 104 | i2c_status_t i2c_start(uint8_t address); | 103 | i2c_status_t i2c_start(uint8_t address); |
| 105 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout); | 104 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout); |
| 106 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); | 105 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout); |
| 107 | i2c_status_t i2c_transmit_receive(uint8_t address, uint8_t * tx_body, uint16_t tx_length, uint8_t * rx_body, uint16_t rx_length); | 106 | i2c_status_t i2c_transmit_receive(uint8_t address, uint8_t* tx_body, uint16_t tx_length, uint8_t* rx_body, uint16_t rx_length); |
| 108 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout); | 107 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout); |
| 109 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); | 108 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout); |
| 110 | void i2c_stop(void); | 109 | void i2c_stop(void); |
