I2C (minor): use CM3 assert instead if manual check
This commit is contained in:
parent
62b83fd34d
commit
f37a6ee4ef
216
lib/i2c_master.c
216
lib/i2c_master.c
|
@ -25,6 +25,7 @@
|
|||
|
||||
/* STM32 (including CM3) libraries */
|
||||
#include <libopencm3/cm3/systick.h> // SysTick library
|
||||
#include <libopencm3/cm3/assert.h> // assert utilities
|
||||
#include <libopencm3/stm32/rcc.h> // real-time control clock library
|
||||
#include <libopencm3/stm32/gpio.h> // general purpose input output library
|
||||
#include <libopencm3/stm32/i2c.h> // I2C library
|
||||
|
@ -39,15 +40,17 @@
|
|||
*/
|
||||
static uint32_t RCC_I2C(uint32_t i2c)
|
||||
{
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
switch (i2c) {
|
||||
case I2C1:
|
||||
return RCC_I2C1;
|
||||
break;
|
||||
case I2C2:
|
||||
return RCC_I2C2;
|
||||
break;
|
||||
default:
|
||||
while (true);
|
||||
case I2C1:
|
||||
return RCC_I2C1;
|
||||
break;
|
||||
case I2C2:
|
||||
return RCC_I2C2;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,13 +60,15 @@ static uint32_t RCC_I2C(uint32_t i2c)
|
|||
*/
|
||||
static uint32_t RCC_GPIO_PORT_SCL(uint32_t i2c)
|
||||
{
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
switch (i2c) {
|
||||
case I2C1:
|
||||
case I2C2:
|
||||
return RCC_GPIOB;
|
||||
break;
|
||||
default:
|
||||
while (true);
|
||||
case I2C1:
|
||||
case I2C2:
|
||||
return RCC_GPIOB;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,13 +78,15 @@ static uint32_t RCC_GPIO_PORT_SCL(uint32_t i2c)
|
|||
*/
|
||||
static uint32_t RCC_GPIO_PORT_SDA(uint32_t i2c)
|
||||
{
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
switch (i2c) {
|
||||
case I2C1:
|
||||
case I2C2:
|
||||
return RCC_GPIOB;
|
||||
break;
|
||||
default:
|
||||
while (true);
|
||||
case I2C1:
|
||||
case I2C2:
|
||||
return RCC_GPIOB;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,19 +96,21 @@ static uint32_t RCC_GPIO_PORT_SDA(uint32_t i2c)
|
|||
*/
|
||||
static uint32_t GPIO_PORT_SCL(uint32_t i2c)
|
||||
{
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
switch (i2c) {
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_BANK_I2C1_RE_SCL;
|
||||
} else {
|
||||
return GPIO_BANK_I2C1_SCL;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_BANK_I2C2_SCL;
|
||||
break;
|
||||
default:
|
||||
while (true);
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_BANK_I2C1_RE_SCL;
|
||||
} else {
|
||||
return GPIO_BANK_I2C1_SCL;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_BANK_I2C2_SCL;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,19 +120,21 @@ static uint32_t GPIO_PORT_SCL(uint32_t i2c)
|
|||
*/
|
||||
static uint32_t GPIO_PORT_SDA(uint32_t i2c)
|
||||
{
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
switch (i2c) {
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_BANK_I2C1_RE_SDA;
|
||||
} else {
|
||||
return GPIO_BANK_I2C1_SDA;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_BANK_I2C2_SDA;
|
||||
break;
|
||||
default:
|
||||
while (true);
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_BANK_I2C1_RE_SDA;
|
||||
} else {
|
||||
return GPIO_BANK_I2C1_SDA;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_BANK_I2C2_SDA;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,19 +144,21 @@ static uint32_t GPIO_PORT_SDA(uint32_t i2c)
|
|||
*/
|
||||
static uint32_t GPIO_PIN_SCL(uint32_t i2c)
|
||||
{
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
switch (i2c) {
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_I2C1_RE_SCL;
|
||||
} else {
|
||||
return GPIO_I2C1_SCL;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_I2C2_SCL;
|
||||
break;
|
||||
default:
|
||||
while (true);
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_I2C1_RE_SCL;
|
||||
} else {
|
||||
return GPIO_I2C1_SCL;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_I2C2_SCL;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,28 +168,27 @@ static uint32_t GPIO_PIN_SCL(uint32_t i2c)
|
|||
*/
|
||||
static uint32_t GPIO_PIN_SDA(uint32_t i2c)
|
||||
{
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
switch (i2c) {
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_I2C1_RE_SDA;
|
||||
} else {
|
||||
return GPIO_I2C1_SDA;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_I2C2_SDA;
|
||||
break;
|
||||
default:
|
||||
while (true);
|
||||
case I2C1:
|
||||
if (AFIO_MAPR & AFIO_MAPR_I2C1_REMAP) {
|
||||
return GPIO_I2C1_RE_SDA;
|
||||
} else {
|
||||
return GPIO_I2C1_SDA;
|
||||
}
|
||||
break;
|
||||
case I2C2:
|
||||
return GPIO_I2C2_SDA;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_master_setup(uint32_t i2c, uint16_t frequency)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
// configure I2C peripheral
|
||||
rcc_periph_clock_enable(RCC_GPIO_PORT_SCL(i2c)); // enable clock for I2C I/O peripheral
|
||||
|
@ -211,10 +223,7 @@ void i2c_master_setup(uint32_t i2c, uint16_t frequency)
|
|||
|
||||
void i2c_master_release(uint32_t i2c)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
i2c_reset(i2c); // reset I2C peripheral configuration
|
||||
i2c_peripheral_disable(i2c); // disable I2C peripheral
|
||||
|
@ -225,10 +234,7 @@ void i2c_master_release(uint32_t i2c)
|
|||
|
||||
bool i2c_master_check_signals(uint32_t i2c)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
// pull SDA and SDC low to check if there are pull-up resistors
|
||||
uint32_t sda_crl = GPIO_CRL(GPIO_PORT_SDA(i2c)); // backup port configuration
|
||||
|
@ -254,10 +260,7 @@ bool i2c_master_check_signals(uint32_t i2c)
|
|||
|
||||
bool i2c_master_reset(uint32_t i2c)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
bool to_return = true;
|
||||
// follow procedure described in STM32F10xxC/D/E Errata sheet, Section 2.14.7
|
||||
|
@ -287,10 +290,7 @@ bool i2c_master_reset(uint32_t i2c)
|
|||
|
||||
enum i2c_master_rc i2c_master_start(uint32_t i2c)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
bool retry = true; // retry after reset if first try failed
|
||||
enum i2c_master_rc to_return; // return code
|
||||
|
@ -340,10 +340,7 @@ try:
|
|||
|
||||
enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool address_10bit, bool write)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1!=i2c && I2C2!=i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
|
||||
if (!(I2C_SR1(i2c) & I2C_SR1_SB)) { // start condition has not been sent
|
||||
|
@ -409,10 +406,7 @@ enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool ad
|
|||
|
||||
enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
// sanity check
|
||||
if (NULL == data || 0 == data_size) { // no data to read
|
||||
|
@ -462,10 +456,7 @@ enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t* data, size_t data_size
|
|||
|
||||
enum i2c_master_rc i2c_master_write(uint32_t i2c, const uint8_t* data, size_t data_size)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
// sanity check
|
||||
if (NULL == data || 0 == data_size) { // no data to write
|
||||
|
@ -499,10 +490,7 @@ enum i2c_master_rc i2c_master_write(uint32_t i2c, const uint8_t* data, size_t da
|
|||
|
||||
enum i2c_master_rc i2c_master_stop(uint32_t i2c)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
// sanity check
|
||||
if (!(I2C_SR2(i2c) & I2C_SR2_BUSY)) { // release is not busy
|
||||
|
@ -550,10 +538,7 @@ enum i2c_master_rc i2c_master_stop(uint32_t i2c)
|
|||
|
||||
enum i2c_master_rc i2c_master_slave_read(uint32_t i2c, uint16_t slave, bool address_10bit, uint8_t* data, size_t data_size)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
|
||||
rc = i2c_master_start(i2c); // send (re-)start condition
|
||||
|
@ -579,10 +564,7 @@ error:
|
|||
|
||||
enum i2c_master_rc i2c_master_slave_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* data, size_t data_size)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
|
||||
rc = i2c_master_start(i2c); // send (re-)start condition
|
||||
|
@ -608,10 +590,7 @@ error:
|
|||
|
||||
enum i2c_master_rc i2c_master_address_read(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, uint8_t* data, size_t data_size)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
|
||||
rc = i2c_master_start(i2c); // send (re-)start condition
|
||||
|
@ -654,10 +633,7 @@ error:
|
|||
|
||||
enum i2c_master_rc i2c_master_address_write(uint32_t i2c, uint16_t slave, bool address_10bit, const uint8_t* address, size_t address_size, const uint8_t* data, size_t data_size)
|
||||
{
|
||||
// check I2C peripheral
|
||||
if (I2C1 != i2c && I2C2 != i2c) {
|
||||
while (true);
|
||||
}
|
||||
cm3_assert(I2C1 == i2c || I2C2 == i2c);
|
||||
|
||||
enum i2c_master_rc rc = I2C_MASTER_RC_NONE; // to store I2C return codes
|
||||
rc = i2c_master_start(i2c); // send (re-)start condition
|
||||
|
|
Loading…
Reference in New Issue