diff options
| author | Nick Brassel <nick@tzarc.org> | 2020-01-23 05:26:52 +1100 |
|---|---|---|
| committer | Nick Brassel <nick@tzarc.org> | 2020-02-01 17:44:39 +1100 |
| commit | 8e550fc11a59326cb759593418ce1a062392daaf (patch) | |
| tree | 41bb317dfdca1a9bbe95a2729de8a2ad8b73ba4c /drivers | |
| parent | 1aee492c0f88b1a96fabdf750a03ed128d9d844a (diff) | |
| download | qmk_firmware-8e550fc11a59326cb759593418ce1a062392daaf.tar.gz qmk_firmware-8e550fc11a59326cb759593418ce1a062392daaf.zip | |
Add thread safety around i2c_master for ChibiOS/ARM.
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/arm/i2c_master.c | 63 |
1 files changed, 51 insertions, 12 deletions
diff --git a/drivers/arm/i2c_master.c b/drivers/arm/i2c_master.c index 21aefd497..b3fabb05e 100644 --- a/drivers/arm/i2c_master.c +++ b/drivers/arm/i2c_master.c | |||
| @@ -29,8 +29,6 @@ | |||
| 29 | #include <string.h> | 29 | #include <string.h> |
| 30 | #include <hal.h> | 30 | #include <hal.h> |
| 31 | 31 | ||
| 32 | static uint8_t i2c_address; | ||
| 33 | |||
| 34 | static const I2CConfig i2cconfig = { | 32 | static const I2CConfig i2cconfig = { |
| 35 | #ifdef USE_I2CV1 | 33 | #ifdef USE_I2CV1 |
| 36 | I2C1_OPMODE, | 34 | I2C1_OPMODE, |
| @@ -71,27 +69,49 @@ __attribute__((weak)) void i2c_init(void) { | |||
| 71 | } | 69 | } |
| 72 | 70 | ||
| 73 | i2c_status_t i2c_start(uint8_t address) { | 71 | i2c_status_t i2c_start(uint8_t address) { |
| 74 | i2c_address = address; | 72 | #if I2C_USE_MUTUAL_EXCLUSION |
| 73 | i2cAcquireBus(&I2C_DRIVER); | ||
| 74 | #endif | ||
| 75 | |||
| 75 | i2cStart(&I2C_DRIVER, &i2cconfig); | 76 | i2cStart(&I2C_DRIVER, &i2cconfig); |
| 76 | return I2C_STATUS_SUCCESS; | 77 | return I2C_STATUS_SUCCESS; |
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { | 80 | i2c_status_t i2c_transmit(uint8_t address, const uint8_t* data, uint16_t length, uint16_t timeout) { |
| 80 | i2c_address = address; | 81 | #if I2C_USE_MUTUAL_EXCLUSION |
| 82 | i2cAcquireBus(&I2C_DRIVER); | ||
| 83 | #endif | ||
| 84 | |||
| 81 | i2cStart(&I2C_DRIVER, &i2cconfig); | 85 | i2cStart(&I2C_DRIVER, &i2cconfig); |
| 82 | msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, 0, 0, MS2ST(timeout)); | 86 | msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (address >> 1), data, length, 0, 0, MS2ST(timeout)); |
| 87 | |||
| 88 | #if I2C_USE_MUTUAL_EXCLUSION | ||
| 89 | i2cReleaseBus(&I2C_DRIVER); | ||
| 90 | #endif | ||
| 91 | |||
| 83 | return chibios_to_qmk(&status); | 92 | return chibios_to_qmk(&status); |
| 84 | } | 93 | } |
| 85 | 94 | ||
| 86 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { | 95 | i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout) { |
| 87 | i2c_address = address; | 96 | #if I2C_USE_MUTUAL_EXCLUSION |
| 97 | i2cAcquireBus(&I2C_DRIVER); | ||
| 98 | #endif | ||
| 99 | |||
| 88 | i2cStart(&I2C_DRIVER, &i2cconfig); | 100 | i2cStart(&I2C_DRIVER, &i2cconfig); |
| 89 | msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (i2c_address >> 1), data, length, MS2ST(timeout)); | 101 | msg_t status = i2cMasterReceiveTimeout(&I2C_DRIVER, (address >> 1), data, length, MS2ST(timeout)); |
| 102 | |||
| 103 | #if I2C_USE_MUTUAL_EXCLUSION | ||
| 104 | i2cReleaseBus(&I2C_DRIVER); | ||
| 105 | #endif | ||
| 106 | |||
| 90 | return chibios_to_qmk(&status); | 107 | return chibios_to_qmk(&status); |
| 91 | } | 108 | } |
| 92 | 109 | ||
| 93 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { | 110 | i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, uint16_t length, uint16_t timeout) { |
| 94 | i2c_address = devaddr; | 111 | #if I2C_USE_MUTUAL_EXCLUSION |
| 112 | i2cAcquireBus(&I2C_DRIVER); | ||
| 113 | #endif | ||
| 114 | |||
| 95 | i2cStart(&I2C_DRIVER, &i2cconfig); | 115 | i2cStart(&I2C_DRIVER, &i2cconfig); |
| 96 | 116 | ||
| 97 | uint8_t complete_packet[length + 1]; | 117 | uint8_t complete_packet[length + 1]; |
| @@ -100,15 +120,34 @@ i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, const uint8_t* data, | |||
| 100 | } | 120 | } |
| 101 | complete_packet[0] = regaddr; | 121 | complete_packet[0] = regaddr; |
| 102 | 122 | ||
| 103 | msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout)); | 123 | msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), complete_packet, length + 1, 0, 0, MS2ST(timeout)); |
| 124 | |||
| 125 | #if I2C_USE_MUTUAL_EXCLUSION | ||
| 126 | i2cReleaseBus(&I2C_DRIVER); | ||
| 127 | #endif | ||
| 128 | |||
| 104 | return chibios_to_qmk(&status); | 129 | return chibios_to_qmk(&status); |
| 105 | } | 130 | } |
| 106 | 131 | ||
| 107 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { | 132 | i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout) { |
| 108 | i2c_address = devaddr; | 133 | #if I2C_USE_MUTUAL_EXCLUSION |
| 134 | i2cAcquireBus(&I2C_DRIVER); | ||
| 135 | #endif | ||
| 136 | |||
| 109 | i2cStart(&I2C_DRIVER, &i2cconfig); | 137 | i2cStart(&I2C_DRIVER, &i2cconfig); |
| 110 | msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (i2c_address >> 1), ®addr, 1, data, length, MS2ST(timeout)); | 138 | msg_t status = i2cMasterTransmitTimeout(&I2C_DRIVER, (devaddr >> 1), ®addr, 1, data, length, MS2ST(timeout)); |
| 139 | |||
| 140 | #if I2C_USE_MUTUAL_EXCLUSION | ||
| 141 | i2cReleaseBus(&I2C_DRIVER); | ||
| 142 | #endif | ||
| 143 | |||
| 111 | return chibios_to_qmk(&status); | 144 | return chibios_to_qmk(&status); |
| 112 | } | 145 | } |
| 113 | 146 | ||
| 114 | void i2c_stop(void) { i2cStop(&I2C_DRIVER); } | 147 | void i2c_stop(void) { |
| 148 | i2cStop(&I2C_DRIVER); | ||
| 149 | |||
| 150 | #if I2C_USE_MUTUAL_EXCLUSION | ||
| 151 | i2cReleaseBus(&I2C_DRIVER); | ||
| 152 | #endif | ||
| 153 | } | ||
