]> git.sur5r.net Git - freertos/commitdiff
Update the Microsemi I2C code to be event driver, rather than polling for Tx complete.
authorrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 25 Apr 2011 14:43:34 +0000 (14:43 +0000)
committerrichardbarry <richardbarry@1d2547de-c912-0410-9cb9-b8ca96c0e9e2>
Mon, 25 Apr 2011 14:43:34 +0000 (14:43 +0000)
git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@1388 1d2547de-c912-0410-9cb9-b8ca96c0e9e2

Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.c
Demo/CORTEX_A2F200_IAR_and_Keil/MicroSemi_Code/drivers/I2C/i2c.h

index 46dbf62170b7e78d5bf93d2e5dfc8514ed5c9468..595e718448a81a02dff0213356c81d58afb69216 100644 (file)
@@ -7,6 +7,8 @@
  * SVN $Revision: 2152 $\r
  * SVN $Date: 2010-02-11 14:44:11 +0000 (Thu, 11 Feb 2010) $\r
  */\r
+\r
+\r
 #include "i2c.h"\r
 #include "../../CMSIS/mss_assert.h"\r
 \r
@@ -145,6 +147,14 @@ void MSS_I2C_init
     this_i2c->hw_reg_bit->CTRL_CR1 = (clock_speed >> 1) & 0x01;\r
     this_i2c->hw_reg_bit->CTRL_CR0 = clock_speed & 0x01;\r
     this_i2c->hw_reg->ADDR = this_i2c->ser_address;\r
+       \r
+       /* The interrupt can cause a context switch, so ensure its priority is\r
+       between configKERNEL_INTERRUPT_PRIORITY and configMAX_SYSCALL_INTERRUPT_PRIORITY. */\r
+       NVIC_SetPriority( this_i2c->irqn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );\r
+       \r
+       vSemaphoreCreateBinary( ( this_i2c->xI2CCompleteSemaphore ) );\r
+       xSemaphoreTake( ( this_i2c->xI2CCompleteSemaphore ), 0 );\r
+       configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );\r
 }\r
 \r
 /*------------------------------------------------------------------------------\r
@@ -196,6 +206,7 @@ void MSS_I2C_write
        uint32_t primask;\r
 \r
     ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );\r
+       configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );\r
 \r
        primask = disable_interrupts();\r
 \r
@@ -431,11 +442,28 @@ mss_i2c_status_t MSS_I2C_wait_complete
 {\r
     ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );\r
 \r
+#ifdef USE_OLD_I2C_POLLING_CODE\r
     while ( this_i2c->status == MSS_I2C_IN_PROGRESS )\r
     {\r
         /* Wait for transaction to compltete.*/\r
         ;\r
     }\r
+#else\r
+       configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );\r
+       if( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED )\r
+       {\r
+               while ( this_i2c->status == MSS_I2C_IN_PROGRESS )\r
+               {\r
+                       /* Wait for transaction to compltete.*/\r
+                       ;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               xSemaphoreTake( this_i2c->xI2CCompleteSemaphore, portMAX_DELAY );\r
+       }\r
+#endif\r
+\r
     return this_i2c->status;\r
 }\r
 \r
@@ -451,12 +479,14 @@ mss_i2c_status_t MSS_I2C_wait_complete
 static void mss_i2c_isr\r
 (\r
        mss_i2c_instance_t * this_i2c\r
-)\r
+               )\r
 {\r
        volatile uint8_t status;\r
        uint8_t data;\r
     uint8_t hold_bus;\r
     uint8_t clear_irq = 1;\r
+       long lHigherPriorityTaskWoken = pdFALSE;\r
+       configASSERT( ( this_i2c->xI2CCompleteSemaphore ) );\r
 \r
     ASSERT( (this_i2c == &g_mss_i2c0) || (this_i2c == &g_mss_i2c1) );\r
 \r
@@ -539,6 +569,7 @@ static void mss_i2c_isr
                     clear_irq = 0;\r
                 }\r
                 this_i2c->status = MSS_I2C_SUCCESS;\r
+                               xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );\r
                        }\r
                        break;\r
 \r
@@ -577,6 +608,7 @@ static void mss_i2c_isr
                     clear_irq = 0;\r
                 }\r
                 this_i2c->status = MSS_I2C_SUCCESS;\r
+                               xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );\r
                        }\r
             break;\r
 \r
@@ -600,6 +632,7 @@ static void mss_i2c_isr
                case ST_SLAR_NACK: /* SLA+R tx'ed; let's release the bus (send a stop condition) */\r
             this_i2c->hw_reg_bit->CTRL_STO = 0x01;\r
             this_i2c->status = MSS_I2C_FAILED;\r
+                       xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );\r
                        break;\r
 \r
                case ST_RX_DATA_ACK: /* Data byte received, ACK returned */\r
@@ -630,6 +663,7 @@ static void mss_i2c_isr
             }\r
 \r
             this_i2c->status = MSS_I2C_SUCCESS;\r
+//                     xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );\r
             break;\r
 \r
                /******************** SLAVE RECEIVER **************************/\r
@@ -696,6 +730,7 @@ static void mss_i2c_isr
                        }\r
                        /* Mark any previous master write transaction as complete. */\r
             this_i2c->status = MSS_I2C_SUCCESS;\r
+//                     xSemaphoreGiveFromISR( this_i2c->xI2CCompleteSemaphore, &lHigherPriorityTaskWoken );\r
                        break;\r
 \r
                case ST_SLV_RST: /* SMBUS ONLY: timeout state. must clear interrupt */\r
@@ -747,6 +782,8 @@ static void mss_i2c_isr
     /* Read the status register to ensure the last I2C registers write took place\r
      * in a system built around a bus making use of posted writes. */\r
     status = this_i2c->hw_reg->STATUS;\r
+       \r
+       portEND_SWITCHING_ISR( lHigherPriorityTaskWoken );\r
 }\r
 \r
 /*------------------------------------------------------------------------------\r
index 63220c37c8856f06c17b5943963801bc5eccaf16..c26b476d61af733f5f1294566079cd10c97964c1 100644 (file)
 \r
 #include "../../CMSIS/a2fxxxm3.h"\r
 \r
+/* FreeRTOS includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+#include "semphr.h"\r
+\r
 #ifdef __cplusplus\r
 extern "C" {\r
 #endif\r
@@ -324,7 +329,10 @@ typedef struct mss_i2c_instance
        /* Slave data: */\r
        uint_fast8_t slave_mem_offset_length;\r
        mss_i2c_slave_wr_handler_t slave_write_handler;\r
-\r
+       \r
+       /* Used to get access to and wait for completion of an I2C transaction. */\r
+       xSemaphoreHandle xI2CCompleteSemaphore;\r
+       \r
 } mss_i2c_instance_t;\r
 \r
 /*-------------------------------------------------------------------------*//**\r