Mbed for VNG board

Fork of mbed-src by mbed official

Files at this revision

API Documentation at this revision

Comitter:
mbed_official
Date:
Tue Dec 09 14:30:09 2014 +0000
Parent:
429:cc5da43e7bf6
Child:
431:255afbe6270c
Commit message:
Synchronized with git revision 0f2b2cdf092ac0325f6003d3e903308446f2da6f

Full URL: https://github.com/mbedmicro/mbed/commit/0f2b2cdf092ac0325f6003d3e903308446f2da6f/

Targets: RZ_A1H - Fix some bugs about I2C, SPI, Interruptin and add terminal definition of user button.

Changed in this revision

targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/PinNames.h Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/gpio_irq_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/spi_api.c Show annotated file Show diff for this revision Revisions of this file
targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/us_ticker.c Show annotated file Show diff for this revision Revisions of this file
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/PinNames.h	Tue Dec 09 14:15:07 2014 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/PinNames.h	Tue Dec 09 14:30:09 2014 +0000
@@ -97,6 +97,9 @@
     I2C_SCL = D15,
     I2C_SDA = D14,
 
+    USER_BUTTON0 = P6_0,
+    USER_BUTTON1 = P6_1,
+
     // Not connected
     NC = (int)0xFFFFFFFF
 } PinName;
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/gpio_irq_api.c	Tue Dec 09 14:15:07 2014 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/gpio_irq_api.c	Tue Dec 09 14:30:09 2014 +0000
@@ -19,10 +19,20 @@
 #include "intc_iodefine.h"
 #include "pinmap.h"
 #include "cmsis.h"
+#include "gpio_addrdefine.h"
 
 #define CHANNEL_NUM     8
 
-static uint32_t channel_ids[CHANNEL_NUM] = {0};
+static void gpio_irq0(void);
+static void gpio_irq1(void);
+static void gpio_irq2(void);
+static void gpio_irq3(void);
+static void gpio_irq4(void);
+static void gpio_irq5(void);
+static void gpio_irq6(void);
+static void gpio_irq7(void);
+
+static gpio_irq_t *channel_obj[CHANNEL_NUM] = {NULL};
 static gpio_irq_handler irq_handler;
 static const int nIRQn_h = 32;
 extern PinName gpio_multi_guard;
@@ -35,6 +45,17 @@
 
 } IRQNo;
 
+static const IRQHandler irq_tbl[CHANNEL_NUM] = {
+    &gpio_irq0,
+    &gpio_irq1,
+    &gpio_irq2,
+    &gpio_irq3,
+    &gpio_irq4,
+    &gpio_irq5,
+    &gpio_irq6,
+    &gpio_irq7,
+};
+
 static const PinMap PinMap_IRQ[] = {
     {P1_0,  IRQ0, 4}, {P1_1,  IRQ1, 4}, {P1_2,  IRQ2, 4},
     {P1_3,  IRQ3, 4}, {P1_5,  IRQ5, 4}, {P1_7,  IRQ7, 4},
@@ -62,22 +83,77 @@
     {NC,    NC,     0}
 };
 
-static gpio_irq_event irq_event;
+static void handle_interrupt_in(int irq_num) {
+    uint16_t irqs;
+    uint16_t edge_req;
+    gpio_irq_t *obj;
+    gpio_irq_event irq_event;
 
-static void handle_interrupt_in(void) {
-    int i;
-    uint16_t irqs;
-    
     irqs = INTCIRQRR;
-    for(i = 0; i< 8; i++) {
-        if (channel_ids[i] && (irqs & (1 << i))) {
-            irq_handler(channel_ids[i], irq_event);
-            INTCIRQRR &= ~(1 << i);
-            GIC_EndInterrupt((IRQn_Type)(nIRQn_h + i));
+    if (irqs & (1 << irq_num)) {
+        obj = channel_obj[irq_num];
+        if (obj != NULL) {
+            edge_req = ((INTCICR1 >> (obj->ch * 2)) & 3);
+            if (edge_req == 1) {
+                irq_event = IRQ_FALL;
+            } else if (edge_req == 2) {
+                irq_event = IRQ_RISE;
+            } else {
+                uint32_t      mask    = (1 << (obj->pin & 0x0F));
+                __I  uint32_t *reg_in = (volatile uint32_t *) PPR((int)PINGROUP(obj->pin));
+
+                if ((*reg_in & mask) == 0) {
+                    irq_event = IRQ_FALL;
+                } else {
+                    irq_event = IRQ_RISE;
+                }
+	        }
+            irq_handler(obj->port, irq_event);
         }
+        INTCIRQRR &= ~(1 << irq_num);
     }
 }
 
+static void gpio_irq0(void) {
+    handle_interrupt_in(0);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 0));
+}
+
+static void gpio_irq1(void) {
+    handle_interrupt_in(1);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 1));
+}
+
+static void gpio_irq2(void) {
+    handle_interrupt_in(2);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 2));
+}
+
+static void gpio_irq3(void) {
+    handle_interrupt_in(3);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 3));
+}
+
+static void gpio_irq4(void) {
+    handle_interrupt_in(4);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 4));
+}
+
+static void gpio_irq5(void) {
+    handle_interrupt_in(5);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 5));
+}
+
+static void gpio_irq6(void) {
+    handle_interrupt_in(6);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 6));
+}
+
+static void gpio_irq7(void) {
+    handle_interrupt_in(7);
+    GIC_EndInterrupt((IRQn_Type)(nIRQn_h + 7));
+}
+
 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
     int shift;
     if (pin == NC) return -1;
@@ -85,19 +161,18 @@
     obj->ch = pinmap_peripheral(pin, PinMap_IRQ);
     obj->pin = (int)pin ;
     obj->port = (int)id ;
-    
+
     shift = obj->ch*2;
-    channel_ids[obj->ch] = id;
+    channel_obj[obj->ch] = obj;
     irq_handler = handler;
     
     pinmap_pinout(pin, PinMap_IRQ);
     gpio_multi_guard = pin;           /* Set multi guard */
 
     // INTC settings
-    InterruptHandlerRegister((IRQn_Type)(nIRQn_h+obj->ch), (void (*)(uint32_t))handle_interrupt_in);
+    InterruptHandlerRegister((IRQn_Type)(nIRQn_h+obj->ch), (void (*)(uint32_t))irq_tbl[obj->ch]);
     INTCICR1 &= ~(0x3 << shift);
     INTCICR1 |= (0x3 << shift);
-    irq_event = IRQ_RISE;
     GIC_SetPriority((IRQn_Type)(nIRQn_h+obj->ch), 5);
     GIC_EnableIRQ((IRQn_Type)(nIRQn_h+obj->ch));
     __enable_irq();
@@ -106,7 +181,7 @@
 }
 
 void gpio_irq_free(gpio_irq_t *obj) {
-    channel_ids[obj->ch] = 0;
+    channel_obj[obj->ch] = NULL;
 }
 
 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
@@ -134,13 +209,6 @@
         INTCIRQRR = (work_irqrr_val & ~(1 << obj->ch));
     } else {
         /* Edge interrupt setting */
-        if ((work_icr_val & (3 << shift)) == 2) {
-            /* Setting of rising edge */
-            irq_event = IRQ_RISE;
-        } else { 
-            /* Setting of falling edge of both edge */
-            irq_event = IRQ_FALL;
-        }
         GIC_EnableIRQ((IRQn_Type)(nIRQn_h+obj->ch));
     }
     INTCICR1  = work_icr_val;
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c	Tue Dec 09 14:15:07 2014 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/i2c_api.c	Tue Dec 09 14:30:09 2014 +0000
@@ -110,6 +110,23 @@
 }
 
 
+static int i2c_wait_STOP(i2c_t *obj) {
+    volatile uint32_t work_reg;
+
+    /* wait SR2.STOP = 1 */
+    work_reg = REG(SR2.UINT32);
+    while ((work_reg & (1 << 3)) == 0) {
+        work_reg = REG(SR2.UINT32);
+    }
+    /* SR2.NACKF = 0 */
+    REG(SR2.UINT32) &= ~(1 << 4);
+    /* SR2.STOP  = 0 */
+    REG(SR2.UINT32) &= ~(1 << 3);
+    
+    return 0;
+}
+
+
 static inline void i2c_power_enable(i2c_t *obj) {
     volatile uint8_t dummy;
     switch ((int)obj->i2c) {
@@ -126,7 +143,6 @@
     I2CName i2c_sda = (I2CName)pinmap_peripheral(sda, PinMap_I2C_SDA);
     I2CName i2c_scl = (I2CName)pinmap_peripheral(scl, PinMap_I2C_SCL);
     obj->i2c = pinmap_merge(i2c_sda, i2c_scl);
-    obj->dummy = 1;
     MBED_ASSERT((int)obj->i2c != NC);
 
     // enable power
@@ -146,25 +162,17 @@
     if (REG(CR2.UINT32) & (1 << 7)) { // BBSY check
         return 0xff;
     }
-    REG(CR2.UINT8[0]) |= 0x62; // start
+    REG(CR2.UINT8[0]) |= 0x02; // start
 
     return 0x10;
 }
 
 inline int i2c_stop(i2c_t *obj) {
-    volatile int timeout = 0;
-
+    /* SR2.STOP  = 0 */
+    REG(SR2.UINT32) &= ~(1 << 3);
     // write the stop bit
     REG(CR2.UINT32) |= (1 << 3);
 
-    // wait for SP bit to reset
-    while(REG(CR2.UINT32) & (1 << 3)) {
-        timeout ++;
-        if (timeout > 100000) return 1;
-    }
-
-    obj->dummy = 1;
-    REG(CR2.UINT32) &= ~ (1 << 3);
     return 0;
 }
 
@@ -194,10 +202,14 @@
         REG(MR3.UINT32) |= (1 << 6);
     } else if (last == 1) {
         // send a NOT ACK
+        REG(MR3.UINT32) |= (1 <<4);
         REG(MR3.UINT32) |=  (1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
     } else {
         // send a ACK
+        REG(MR3.UINT32) |= (1 <<4);
         REG(MR3.UINT32) &= ~(1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
     }
 
     // return the data
@@ -269,20 +281,22 @@
     int value;
     volatile uint32_t work_reg = 0;
 
-
     // full reset
     i2c_reg_reset(obj);
-
+    obj->dummy = 1;
+    
     status = i2c_start(obj);
 
     if (status == 0xff) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_BUS_BUSY;
     }
 
     status = i2c_do_write(obj, (address | 0x01));
     if (status & 0x01) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_NO_SLAVE;
     }
     
@@ -292,11 +306,14 @@
     if ((REG(SR2.UINT32) & (1 << 4) == 1)) {
         /* Slave sends NACK */
         i2c_stop(obj);
+        // dummy read
+        value = REG(DRR.UINT32);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_NO_SLAVE;
     }
     
     // Read in all except last byte
-    if (length > 1) {
+    if (length > 2) {
         for (count = 0; count < (length - 1); count++) {
             if (count == (length - 2)) {
                 value = i2c_do_read(obj, 1);
@@ -308,41 +325,55 @@
             status = i2c_status(obj);
             if (status & 0x10) {
                 i2c_stop(obj);
+                i2c_wait_STOP(obj);
                 return count;
             }
             data[count] = (char) value;
         }
+    } else if (length == 2) {
+        /* Set MR3 WATI bit is 1 */;
+        REG(MR3.UINT32) |= (1 << 6);
+        // dummy read
+        value = REG(DRR.UINT32);
+        // wait for it to arrive
+        i2c_wait_RDRF(obj);
+        // send a NOT ACK
+        REG(MR3.UINT32) |= (1 <<4);
+        REG(MR3.UINT32) |=  (1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
+        data[count] = (char)REG(DRR.UINT32);
+        count++;
+    } else if (length == 1) {
+        /* Set MR3 WATI bit is 1 */;
+        REG(MR3.UINT32) |= (1 << 6);
+        // send a NOT ACK
+        REG(MR3.UINT32) |= (1 <<4);
+        REG(MR3.UINT32) |=  (1 <<3);
+        REG(MR3.UINT32) &= ~(1 <<4);
+        // dummy read
+        value = REG(DRR.UINT32);
+    } else {
+        // Do Nothing
     }
 
     // read in last byte
     i2c_wait_RDRF(obj);
-    /* RIICnSR2.STOP = 0 */
-    REG(SR2.UINT32) &= ~(1 << 3);
-    /* RIICnCR2.SP   = 1 */
-    REG(CR2.UINT32) |= (1 << 3);
-    /* RIICnDRR read */
-    value = REG(DRR.UINT32) & 0xFF;
-    /* RIICnMR3.WAIT = 0 */
-    REG(MR3.UINT32) &= ~(1 << 6);
-    /* wait SR2.STOP = 1 */
-    while ((work_reg & (1 << 3)) == (1 << 3)) {
-        work_reg = REG(SR2.UINT32);
-    }
-    /* SR2.NACKF = 0 */
-    REG(SR2.UINT32) &= ~(1 << 4);
-    /* SR2.STOP  = 0 */
-    REG(SR2.UINT32) &= ~(1 << 3);
-    status = i2c_status(obj);
-    if (status & 0x10) {
-        i2c_stop(obj);
-        return length - 1;
-    }
-
-    data[count] = (char) value;
-
     // If not repeated start, send stop.
     if (stop) {
-        i2c_stop(obj);
+        /* RIICnSR2.STOP = 0 */
+        REG(SR2.UINT32) &= ~(1 << 3);
+        /* RIICnCR2.SP   = 1 */
+        REG(CR2.UINT32) |= (1 << 3);
+        /* RIICnDRR read */
+        value = REG(DRR.UINT32) & 0xFF;
+        data[count] = (char) value;
+        /* RIICnMR3.WAIT = 0 */
+        REG(MR3.UINT32) &= ~(1 << 6);
+        i2c_wait_STOP(obj);
+    } else {
+        /* RIICnDRR read */
+        value = REG(DRR.UINT32) & 0xFF;
+        data[count] = (char) value;
     }
 
     return length;
@@ -358,19 +389,35 @@
 
     if ((status == 0xff)) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_BUS_BUSY;
     }
+    
+    /**/
+    status = REG(CR2.UINT32);
+    status = REG(SR2.UINT32);
+    /**/
 
     status = i2c_do_write(obj, address);
     if (status & 0x10) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
         return I2C_ERROR_NO_SLAVE;
     }
 
+    /**/
+    status = REG(CR2.UINT32);
+    status = REG(SR2.UINT32);
+    /**/
     for (i=0; i<length; i++) {
+    /**/
+    status = REG(CR2.UINT32);
+    status = REG(SR2.UINT32);
+    /**/
         status = i2c_do_write(obj, data[i]);
         if(status & 0x10) {
             i2c_stop(obj);
+            i2c_wait_STOP(obj);
             return i;
         }
     }
@@ -380,6 +427,7 @@
     // If not repeated start, send stop.
     if (stop) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
     }
 
     return length;
@@ -387,9 +435,12 @@
 
 void i2c_reset(i2c_t *obj) {
     i2c_stop(obj);
+    i2c_wait_STOP(obj);
 }
 
 int i2c_byte_read(i2c_t *obj, int last) {
+    obj->dummy = 1;
+    
     return (i2c_do_read(obj, last) & 0xFF);
 }
 
@@ -432,10 +483,7 @@
     int count = 0;
     int status;
 
-    if (obj->dummy) {
-        volatile int dummy = REG(DRR.UINT32) ;
-        obj->dummy = 0;
-    }
+    volatile int dummy = REG(DRR.UINT32) ;
 
     do {
         i2c_wait_RDRF(obj);
@@ -448,6 +496,7 @@
 
     if(status & 0x10) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
     }
 
     //i2c_clear_TDRE(obj);
@@ -470,6 +519,7 @@
 
     if (!(status & 0x10)) {
         i2c_stop(obj);
+        i2c_wait_STOP(obj);
     }
 
     i2c_clear_TDRE(obj);
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/spi_api.c	Tue Dec 09 14:15:07 2014 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/spi_api.c	Tue Dec 09 14:30:09 2014 +0000
@@ -157,7 +157,7 @@
     spi_disable(obj);
     const int P1CLK = 66666666; // 66.6666MHz
     uint8_t div, brdv;
-    uint16_t mask = 0x000c0;
+    uint16_t mask = 0x000c;
 
     if (hz <= P1CLK/2 && hz >= P1CLK/255) {
         div = (P1CLK / hz / 2) -1;
--- a/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/us_ticker.c	Tue Dec 09 14:15:07 2014 +0000
+++ b/targets/hal/TARGET_RENESAS/TARGET_RZ_A1H/us_ticker.c	Tue Dec 09 14:30:09 2014 +0000
@@ -16,81 +16,74 @@
 #include <stddef.h>
 #include "us_ticker_api.h"
 #include "PeripheralNames.h"
-#include "mtu2_iodefine.h"
+#include "ostm_iodefine.h"
+
+#include "RZ_A1_Init.h"
+#include "MBRZA1H.h"
 
-#define US_TICKER_TIMER      (OSTM0.OSTMnCMP)
-#define US_TICKER_TIMER_IRQn TIMER3_IRQn
+#define US_TICKER_TIMER_IRQn (OSTMI1TINT_IRQn)
+#define CPG_STBCR5_BIT_MSTP50   (0x01u) /* OSTM1 */
+
+#define US_TICKER_CLOCK_US_DEV (1000000)
 
 int us_ticker_inited = 0;
+static double count_clock = 0;
 
 void us_ticker_interrupt(void) {
     us_ticker_irq_handler();
-    GIC_EndInterrupt(TGI2A_IRQn);
 }
 
 void us_ticker_init(void) {
     if (us_ticker_inited) return;
     us_ticker_inited = 1;
     
+    /* set Counter Clock(us) */
+    if (false == RZ_A1_IsClockMode0()) {
+        count_clock = (double)(CM1_RENESAS_RZ_A1_P0_CLK / US_TICKER_CLOCK_US_DEV);
+    } else {
+        count_clock = (double)(CM0_RENESAS_RZ_A1_P0_CLK / US_TICKER_CLOCK_US_DEV);
+    }
+
     /* Power Control for Peripherals      */
-    CPGSTBCR3 &= ~ 0x8;   // turn on MTU2
+    CPGSTBCR5 &= ~(CPG_STBCR5_BIT_MSTP50); /* enable OSTM1 clock */
 
     // timer settings
-    MTU2.TSYR = 0x6;      // cascading T_1-T_2
-
-    MTU2.TCR_2 = 0x03;    // divider 1/64
-    MTU2.TCR_1 = 0x07;    // count-up from T_2 pulse(cascade)
+    OSTM1TT   = 0x01;    /* Stop the counter and clears the OSTM1TE bit.     */
+    OSTM1CTL  = 0x02;    /* Free running timer mode. Interrupt disabled when star counter  */
 
-    MTU2.TCNT_1 = 0x00;   // counter value set to 0
-    MTU2.TCNT_2 = 0x00;   // 
-
-    MTU2.TSTR |= 0x06;     //
-    MTU2.TSR_2 = 0xc0;    // timer start
+    OSTM1TS   = 0x1;    /* Start the counter and sets the OSTM0TE bit.     */
 
     // INTC settings
-    InterruptHandlerRegister(TGI2A_IRQn, (void (*)(uint32_t))us_ticker_interrupt);
-    GIC_SetPriority(TGI2A_IRQn, 5);
-    GIC_EnableIRQ(TGI2A_IRQn);
-    __enable_irq();
+    InterruptHandlerRegister(US_TICKER_TIMER_IRQn, (void (*)(uint32_t))us_ticker_interrupt);
+    GIC_SetPriority(US_TICKER_TIMER_IRQn, 5);
+    GIC_EnableIRQ(US_TICKER_TIMER_IRQn);
 }
 
-//static const float PCLK     =33.33,          // dummy
-                   //PRESCALE =64.0;           // dummy
-static const float FACTOR_C2U = 1.9201920192019204, //(PRESCALE/PCLK)
-                   FACTOR_U2C = 0.52078125;         //(PCLK/PRESCALE)
-
-#define F_CLK2us(val)  ((uint32_t)((val)*FACTOR_C2U))
-#define F_us2CLK(val)  ((uint32_t)((val)*FACTOR_U2C))
-
-
 uint32_t us_ticker_read() {
-    static uint32_t max_val = 0x8551eb85; //*F_us2CLK(0xffffffff)+1;
     uint32_t val;
     if (!us_ticker_inited)
         us_ticker_init();
     
-    val = MTU2.TCNT_1<<16 | MTU2.TCNT_2;  // concat cascaded Counters
-    if (val > max_val) {  // if overflow (in us-timer)
-        val -= max_val;   // correct value
-        MTU2.TCNT_1 = 0;  // reset counter
-        MTU2.TCNT_2 = val;
-    }
-    val = F_CLK2us(val);
+    /* read counter */
+    val = OSTM1CNT;
+    
+    /* clock to us */
+    val = (uint32_t)(val / count_clock);
     return val;
 }
 
 void us_ticker_set_interrupt(timestamp_t timestamp) {
     // set match value
-    timestamp = F_us2CLK(timestamp);
-    MTU2.TGRA_2 = timestamp & 0xffff;
-    // enable match interrupt
-    MTU2.TIER_2 = 0x01;
+    timestamp = (timestamp_t)(timestamp * count_clock);
+    OSTM1CMP  = (uint32_t)(timestamp & 0xffffffff);
+    GIC_EnableIRQ(US_TICKER_TIMER_IRQn);
 }
 
 void us_ticker_disable_interrupt(void) {
-    MTU2.TIER_2 &= ~(0xc0);
+    GIC_DisableIRQ(US_TICKER_TIMER_IRQn);
 }
 
 void us_ticker_clear_interrupt(void) {
-    MTU2.TSR_2 &= 0xc0;
+    /* There are no Flags of OSTM1 to clear here */
+    /* Do Nothing */
 }