summaryrefslogtreecommitdiffstats
path: root/bsps
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-10-01 08:59:14 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-10-01 09:01:29 +0200
commit5cb23f4b8870499b306cfb99186aa484ed0a47f1 (patch)
tree252a6308a828e16213d8cd2af024397383566988 /bsps
parentbsp/atsam: Use binary semaphore for SPI (diff)
downloadrtems-5cb23f4b8870499b306cfb99186aa484ed0a47f1.tar.bz2
bsp/atsam: Use binary semaphore for I2C
Remove superfluous sleep before each I2C transfer. Reset I2C module after transfer timeouts. Update #3534.
Diffstat (limited to 'bsps')
-rw-r--r--bsps/arm/atsam/i2c/atsam_i2c_bus.c39
-rw-r--r--bsps/arm/atsam/include/bsp/atsam-i2c.h5
2 files changed, 21 insertions, 23 deletions
diff --git a/bsps/arm/atsam/i2c/atsam_i2c_bus.c b/bsps/arm/atsam/i2c/atsam_i2c_bus.c
index bace7e656e..4425975de8 100644
--- a/bsps/arm/atsam/i2c/atsam_i2c_bus.c
+++ b/bsps/arm/atsam/i2c/atsam_i2c_bus.c
@@ -267,11 +267,8 @@ atsam_i2c_interrupt(void *arg)
atsam_i2c_next_packet(bus);
if (bus->msg_todo == 0 || err != 0) {
- rtems_status_code sc;
-
atsam_i2c_disable_interrupts(regs);
- sc = rtems_event_transient_send(bus->task_id);
- assert(sc == RTEMS_SUCCESSFUL);
+ rtems_binary_semaphore_post(&bus->sem);
} else {
atsam_i2c_setup_transfer(bus, regs);
}
@@ -281,15 +278,13 @@ atsam_i2c_interrupt(void *arg)
static int
atsam_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)
{
- rtems_status_code sc;
atsam_i2c_bus *bus = (atsam_i2c_bus *)base;
Twihs *regs;
uint32_t i;
-
- rtems_task_wake_after(1);
+ int eno;
if (msg_count < 1){
- return 1;
+ return 0;
}
for (i = 0; i < msg_count; ++i) {
@@ -302,7 +297,6 @@ atsam_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)
bus->msg_todo = msg_count;
bus->current_msg_todo = msgs[0].len;
bus->current_msg_byte = msgs[0].buf;
- bus->task_id = rtems_task_self();
regs = bus->regs;
@@ -310,9 +304,13 @@ atsam_i2c_transfer(i2c_bus *base, i2c_msg *msgs, uint32_t msg_count)
regs->TWIHS_IER = ATSAMV_I2C_IRQ_ERROR;
- sc = rtems_event_transient_receive(RTEMS_WAIT, bus->base.timeout);
- if (sc != RTEMS_SUCCESSFUL){
- rtems_event_transient_clear();
+ eno = rtems_binary_semaphore_wait_timed_ticks(
+ &bus->sem,
+ bus->base.timeout
+ );
+ if (eno != 0) {
+ TWI_ConfigureMaster(bus->regs, bus->output_clock, BOARD_MCK);
+ rtems_binary_semaphore_try_wait(&bus->sem);
return -ETIMEDOUT;
}
@@ -323,8 +321,8 @@ static int
atsam_i2c_set_clock(i2c_bus *base, unsigned long clock)
{
atsam_i2c_bus *bus = (atsam_i2c_bus *)base;
- Twihs *regs = bus->regs;
- TWI_ConfigureMaster(regs, clock, BOARD_MCK);
+ bus->output_clock = clock;
+ TWI_ConfigureMaster(bus->regs, clock, BOARD_MCK);
return 0;
}
@@ -341,8 +339,7 @@ atsam_i2c_destroy(i2c_bus *base)
}
static void
-atsam_i2c_init(atsam_i2c_bus *bus, uint32_t input_clock, Twihs *board_base,
- uint32_t board_id, const Pin *pins)
+atsam_i2c_init(atsam_i2c_bus *bus, uint32_t board_id, const Pin *pins)
{
/* Initialize the TWI */
@@ -351,7 +348,7 @@ atsam_i2c_init(atsam_i2c_bus *bus, uint32_t input_clock, Twihs *board_base,
/* Enable the TWI clock */
ENABLE_PERIPHERAL(board_id);
- TWI_ConfigureMaster(board_base, input_clock, BOARD_MCK);
+ TWI_ConfigureMaster(bus->regs, bus->output_clock, BOARD_MCK);
}
int
@@ -364,22 +361,22 @@ i2c_bus_register_atsam(
{
atsam_i2c_bus *bus;
rtems_status_code sc;
- uint32_t board_id = (uint32_t) irq;
bus = (atsam_i2c_bus *) i2c_bus_alloc_and_init(sizeof(*bus));
if (bus == NULL){
return -1;
}
+ rtems_binary_semaphore_init(&bus->sem, "ATSAM I2C");
bus->regs = register_base;
bus->irq = irq;
+ bus->output_clock = I2C_BUS_CLOCK_DEFAULT;
- atsam_i2c_init(bus, I2C_BUS_CLOCK_DEFAULT, bus->regs,
- board_id, pins);
+ atsam_i2c_init(bus, irq, pins);
sc = rtems_interrupt_handler_install(
irq,
- "Atsamv_I2C",
+ "ATSAM I2C",
RTEMS_INTERRUPT_UNIQUE,
atsam_i2c_interrupt,
bus
diff --git a/bsps/arm/atsam/include/bsp/atsam-i2c.h b/bsps/arm/atsam/include/bsp/atsam-i2c.h
index 7425db9f7b..ae0fe97584 100644
--- a/bsps/arm/atsam/include/bsp/atsam-i2c.h
+++ b/bsps/arm/atsam/include/bsp/atsam-i2c.h
@@ -19,6 +19,7 @@
#include <libchip/include/pio.h>
#include <bsp.h>
+#include <rtems/thread.h>
#include <dev/i2c/i2c.h>
#ifdef __cplusplus
@@ -54,9 +55,9 @@ typedef struct {
uint32_t msg_todo;
uint32_t current_msg_todo;
uint8_t *current_msg_byte;
- uint32_t input_clock;
+ uint32_t output_clock;
bool read;
- rtems_id task_id;
+ rtems_binary_semaphore sem;
rtems_vector_number irq;
} atsam_i2c_bus;