[PATCH v2 2/2] bsp: improved documentation in Beaglebone qep driver

James Fitzsimons james.fitzsimons at gmail.com
Tue Aug 25 09:56:58 UTC 2020


---
 bsps/arm/beagle/include/bsp/qep.h | 59 ++++++++++++++++++++++++++++---
 bsps/arm/beagle/qep/qep.c         | 14 ++++++--
 2 files changed, 67 insertions(+), 6 deletions(-)

diff --git a/bsps/arm/beagle/include/bsp/qep.h b/bsps/arm/beagle/include/bsp/qep.h
index 671d9cca6c..fc086e3c80 100644
--- a/bsps/arm/beagle/include/bsp/qep.h
+++ b/bsps/arm/beagle/include/bsp/qep.h
@@ -168,19 +168,63 @@ typedef enum {
 } bbb_qep_pin;
 
 
-typedef void (*bbb_eqep_timer_callback)(BBB_PWMSS);
+/**
+ * @brief This function definition is used to declare a callback function that
+ * will be called by the interrupt handler of the QEP driver. In order for the
+ * interrupt event to trigger the driver must be configured in RELATIVE mode
+ * (using the beagle_qep_get_quadrature_mode function), and the unit timer must
+ * have been configured (using the beagle_eqep_set_timer_period function).
+ *
+ * @param BBB_PWMSS This argument is provided to the user call back function so
+ * that the user can tell which QEP module raised the interrupt.
+ *
+ * @param position The value of the position counter that was latched when the
+ * unit timer raised this interrupt. This is the value that would be returned
+ * by calling "beagle_qep_get_position".
+ *
+ * @param user This a pointer to a user provided data structure. The user sets
+ * this pointer value when configuring the unit timer callback via the
+ * beagle_eqep_set_timer_period function and it is returned here as an argument.
+ * The driver does not touch this value.
+ */
+typedef void (*bbb_eqep_timer_callback)(
+  BBB_PWMSS,
+  uint32_t position,
+  void* user
+);
 
 
 /**
- * @brief This structure represents an eQEP module instance.
+ * @brief This structure represents an eQEP module instance. The members
+ * represent the configuration of a specific eQEP module. There are three
+ * eQEP modules in the AM335x, one associated with each PWMSS unit.
+ * @var bbb_eqep::pwmss_id The PWMSS unit this eQEP module belongs to.
+ * @var bbb_eqep::mmio_base The base address for this eQEP modules registers
+ * @var bbb_eqep::irq The IRQ vector for this eQEP module
+ * @var bbb_eqep::timer_callback An optional user provided callback function
+ * when the driver is configured in RELATIVE mode using the unit timer
+ * @var bbb_eqep::user An optional pointer to user provided data that will be
+ * handed to the callback function as an argument.
+ * @var bbb_eqep::count_mode The count mode for this eQEP module. Defaults to
+ * QUADRATURE.
+ * @var bbb_eqep::quadrature_mode The mode for QUADRATURE operation. Defaults
+ * to ABSOLUTE - will count up to overflow or until the user resets the
+ * position. Can be set to RELATIVE which will trigger a call back of the unit
+ * timer if configured.
+ * @var bbb_eqep::invert_qa 1 to invert the A channel input, 0 to leave as is.
+ * @var bbb_eqep::invert_qb 1 to invert the B channel input, 0 to leave as is.
+ * @var bbb_eqep::invert_qi 1 to invert the INDEX input, 0 to leave as is.
+ * @var bbb_eqep::invert_qs 1 to invert the STROBE input, 0 to leave as is.
+ * @var bbb_eqep::swap_inputs 1 to swap the A and B channel inputs, 0 to leave
+ * as is.
  *
- * The members are closely modelled on the FDT structure. *
  */
 typedef struct {
   const BBB_PWMSS pwmss_id;
   const uint32_t mmio_base;
   const rtems_vector_number irq;
   bbb_eqep_timer_callback timer_callback;
+  void* user;
   BBB_QEP_COUNT_MODE count_mode;
   BBB_QEP_QUADRATURE_MODE quadrature_mode;
   uint32_t invert_qa;
@@ -315,13 +359,20 @@ uint32_t beagle_eqep_get_timer_period(BBB_PWMSS pwmss_id);
  * 0 = off, greater than zero sets the period.
  * @param pwmss_id Identifies which PWMSS module to set the eQEP unit timer for.
  * @param period The value in nanoseconds to set the unit timer period to.
+ * @param timer_callback This is the user provided callback function that will
+ * be called by the interrupt event handler on expiry of the unit timer. The
+ * user can provide NULL if they don't require a call back.
+ * @param user This is a pointer to a user provided data structure that will be
+ * handed back as an argument to the timer callback. The driver does not touch
+ * this value.
  * @return RTEMS_SUCCESSFUL if ok, RTEMS_INVALID_ID if an invalid pwmss_id is
  * supplied.
  */
 rtems_status_code beagle_eqep_set_timer_period(
     BBB_PWMSS pwmss_id,
     uint64_t period,
-    bbb_eqep_timer_callback timer_callback
+    bbb_eqep_timer_callback timer_callback,
+    void* user
 );
 
 #ifdef __cplusplus
diff --git a/bsps/arm/beagle/qep/qep.c b/bsps/arm/beagle/qep/qep.c
index d0fc9fc6ba..34eb453258 100644
--- a/bsps/arm/beagle/qep/qep.c
+++ b/bsps/arm/beagle/qep/qep.c
@@ -35,6 +35,7 @@ static bbb_eqep bbb_eqep_table[ BBB_PWMSS_COUNT ] =
   .mmio_base = AM335X_EQEP_0_REGS,
   .irq = AM335X_INT_eQEP0INT,
   .timer_callback = NULL,
+  .user = NULL,
   .count_mode = QUADRATURE_COUNT,
   .quadrature_mode = ABSOLUTE,
   .invert_qa = 0,
@@ -48,6 +49,7 @@ static bbb_eqep bbb_eqep_table[ BBB_PWMSS_COUNT ] =
   .mmio_base = AM335X_EQEP_1_REGS,
   .irq = AM335X_INT_eQEP1INT,
   .timer_callback = NULL,
+  .user = NULL,
   .count_mode = QUADRATURE_COUNT,
   .quadrature_mode = ABSOLUTE,
   .invert_qa = 0,
@@ -61,6 +63,7 @@ static bbb_eqep bbb_eqep_table[ BBB_PWMSS_COUNT ] =
   .mmio_base = AM335X_EQEP_2_REGS,
   .irq = AM335X_INT_eQEP2INT,
   .timer_callback = NULL,
+  .user = NULL,
   .count_mode = QUADRATURE_COUNT,
   .quadrature_mode = ABSOLUTE,
   .invert_qa = 0,
@@ -75,6 +78,7 @@ static bbb_eqep bbb_eqep_table[ BBB_PWMSS_COUNT ] =
 static void beagle_eqep_irq_handler(void *arg)
 {
   uint16_t flags;
+  int32_t position = 0;
   bbb_eqep* eqep = arg;
 
   /* Use the interrupt register (QFLG) mask to determine what caused the
@@ -83,7 +87,8 @@ static void beagle_eqep_irq_handler(void *arg)
   /* Check the interrupt source to see if it was a unit timer overflow  */
   if (flags & AM335x_EQEP_QFLG_UTO && eqep->timer_callback != NULL) {
     /* Handle the unit timer overflow interrupt */
-    eqep->timer_callback(eqep->pwmss_id);
+    position = beagle_qep_get_position(eqep->pwmss_id);
+    eqep->timer_callback(eqep->pwmss_id, position, eqep->user);
   }
 
   /* Clear interrupt flags (write back triggered flags to the clear register) */
@@ -395,7 +400,8 @@ uint32_t beagle_eqep_get_timer_period(BBB_PWMSS pwmss_id)
 rtems_status_code beagle_eqep_set_timer_period(
     BBB_PWMSS pwmss_id,
     uint64_t period,
-    bbb_eqep_timer_callback timer_callback
+    bbb_eqep_timer_callback timer_callback,
+    void* user
 )
 {
   uint16_t qepctl;
@@ -429,6 +435,10 @@ rtems_status_code beagle_eqep_set_timer_period(
     if (timer_callback != NULL) {
       eqep->timer_callback = timer_callback;
     }
+    /* attach the user data if it has been provided */
+    if (user != NULL) {
+      eqep->user = user;
+    }
   }
 
   return RTEMS_SUCCESSFUL;
-- 
2.17.1



More information about the devel mailing list