OSDN Git Service

Ticket #29228 Added the I2C Read and Write Fearutres.
authorShinichiro Nakamura <shinta.main.jp@gmail.com>
Thu, 23 Aug 2012 22:08:48 +0000 (07:08 +0900)
committerShinichiro Nakamura <shinta.main.jp@gmail.com>
Thu, 23 Aug 2012 22:08:48 +0000 (07:08 +0900)
firm/bare_metal/Makefile
firm/bare_metal/at24c.c
firm/bare_metal/ssm2603.c
firm/bare_metal/twi.c
firm/bare_metal/twi.h
firm/bare_metal/uart.c [new file with mode: 0644]
firm/bare_metal/uart.h [new file with mode: 0644]
firm/bare_metal/uzume.c

index ee14274..3f23013 100644 (file)
@@ -8,7 +8,8 @@ PROJECT = bluetank
 #
 CSRC   += lcd.c led.c
 CSRC   += mmc.c pff.c
-CSRC   += twi.c ssm2603.c at24c.c
+CSRC   += twi.c uart.c
+CSRC   += ssm2603.c at24c.c
 CSRC   += bfin_util.c uzume.c
 CSRC   += effect.c main.c
 ASRC   +=
index 19f1845..4763d61 100644 (file)
  * ===============================================================
  */
 
+#include <builtins.h>
 #include "at24c.h"
 #include "twi.h"
+#include "bfin_util.h"
+
+#define DEVICE_PINCONF      (0)
+#define DEVICE_ADDRESS(N)   (0x50 | ((N) & 0x07))
 
 void at24c_init()
 {
-    /*
-     * TWI\e$B$r=i4|2=$9$k!#\e(B
-     */
     twi_init();
 }
 
 void at24c_read(const uint32_t addr, uint8_t *data)
 {
+    uint8_t buf[1];
+    buf[0] = addr;
+    twi_master_write(DEVICE_ADDRESS(DEVICE_PINCONF), TWI_RSTART, &buf[0], 1);
+    while (twi_master_xfer_state() != TWI_STATE_COMP) {
+        ssync();
+    }
+    twi_master_read(DEVICE_ADDRESS(DEVICE_PINCONF), TWI_STOP, data, 1);
+    while (twi_master_xfer_state() != TWI_STATE_COMP) {
+        ssync();
+    }
+    bfin_util_usleep(5000);
 }
 
 void at24c_write(const uint32_t addr, const uint8_t data)
 {
+    uint8_t buf[2];
+    buf[0] = addr;
+    buf[1] = data;
+    twi_master_write(DEVICE_ADDRESS(DEVICE_PINCONF), TWI_STOP, &buf[0], 2);
+    while (twi_master_xfer_state() != TWI_STATE_COMP) {
+        ssync();
+    }
+    bfin_util_usleep(5000);
 }
 
index d089a9c..eefb588 100644 (file)
@@ -34,6 +34,7 @@
  */
 
 #include <cdefBF592-A.h>
+#include <builtins.h>
 #include "twi.h"
 #include "ssm2603.h"
 
@@ -58,7 +59,7 @@ static const uint8_t ssm2603_initdata[] =
 
 void ssm2603_init(void)
 {
-    uint32_t i, j;
+    uint32_t i;
 
     /*
      * TWIを初期化する。
@@ -86,11 +87,8 @@ void ssm2603_init(void)
      */
     for (i = 0; i < sizeof(ssm2603_initdata); i+=2) {
         twi_master_write(TWI_DEVICE_ADDR, TWI_STOP, &ssm2603_initdata[i], 2);
-        /*
-         * STOP CONDITIONから600ns以上空ける
-         */
-        for (j = 0; j < 300; j++) {
-            asm("ssync;");
+        while (twi_master_xfer_state() != TWI_STATE_COMP) {
+            ssync();
         }
     }
 }
index 75d8151..4d06ac0 100644 (file)
  * ===============================================================
  */
 
-#include "twi.h"
 #include <cdefBF592-A.h>
+#include <builtins.h>
+#include <sys/exception.h>
+#include <stdint.h>
+#include "twi.h"
 
 #define TWI_COUNT(x) (DCNT & ((x) << 6))
 
-/**
- * @brief TWI(I2C)を初期化する。
- */
+typedef struct
+{
+    int32_t  state;
+    int32_t  xfer_dir;  /* 0:READ, 1:WRITE */
+    uint8_t* p_data;
+    int32_t  count;
+} twi_xfer_param;
+
+typedef __attribute__((interrupt_handler)) void (*ex_handler_fn_gcc)(void);
+
+/* TWI割り込みのプロトタイプ宣言 */
+static __attribute__((interrupt_handler)) void s_bfin_twi_isr(void);
+
+static twi_xfer_param sf_twi_xfer_param;
+
+/* Visual DSP++のregister_handler関数実装 */
+static void s_bfin_register_handler(interrupt_kind kind, ex_handler_fn_gcc fn)
+{
+    uint32_t l_mask;
+
+    if((ik_emulation > kind) || (kind > ik_ivg15)) return;
+
+    *((ex_handler_fn_gcc*)&(((uint32_t*)EVT0)[(int32_t)kind])) = fn;
+    l_mask  = cli();
+    l_mask |= 1u << (int32_t)kind;
+    sti(l_mask);
+}
+
 void twi_init(void)
 {
     *pTWI_CONTROL = 0;
-    asm("ssync;");
-    *pTWI_CONTROL = TWI_ENA | 10U;
-    *pTWI_CLKDIV  = CLKHI(50) | CLKLOW(50);
+    ssync();
+    *pTWI_CONTROL = 20U;
+    *pTWI_CLKDIV  = CLKHI(12) | CLKLOW(13);
     *pTWI_INT_MASK = RCVSERV | XMTSERV | MERR | MCOMP;
     *pTWI_INT_STAT = *pTWI_INT_STAT;
     *pTWI_FIFO_CTL = XMTFLUSH | RCVFLUSH;
-    asm("ssync;");
+    ssync();
+    *pTWI_FIFO_CTL = 0;
+
+    /* 割り込みハンドラをIVG12に登録 */
+    s_bfin_register_handler(ik_ivg12, s_bfin_twi_isr);
+    *pSIC_IMASK |= IRQ_TWI;
 }
 
-/**
- * @brief TWI(I2C)バスに書き込む。
- *
- * @param slave_addr スレーブアドレス。
- * @param rstart スタートコンディション。
- * @param p_data データ。
- * @param write_cnt 書き込むデータバイト数。
- *
- * @retval NO_ERROR エラーなし。
- * @retval TWI_ERROR_NAK エラー。
- */
-int32_t twi_master_write(uint8_t slave_addr, int32_t rstart, const uint8_t* p_data, int32_t write_cnt)
+void twi_master_write(uint8_t slave_addr, int32_t rstart, const uint8_t* p_data, int32_t write_cnt)
 {
-    int32_t l_idx;
+    if(write_cnt <= 0) return;
 
-    if (write_cnt <= 0) {
-        return NO_ERROR;
-    }
+    sf_twi_xfer_param.state    = TWI_STATE_XFER;
+    sf_twi_xfer_param.xfer_dir = 1;
+    sf_twi_xfer_param.p_data   = (uint8_t*)&p_data[1];
+    sf_twi_xfer_param.count    = write_cnt - 1;
 
-    *pTWI_FIFO_CTL = 0;
-    *pTWI_INT_STAT = *pTWI_INT_STAT;
+    *pTWI_CONTROL |= TWI_ENA;
+    ssync();
+    *pTWI_INT_STAT = MCOMP | MERR | XMTSERV | RCVSERV;
     *pTWI_MASTER_STAT = BUFWRERR | BUFRDERR | LOSTARB | ANAK | DNAK;
     *pTWI_MASTER_ADDR = slave_addr;
-
-    /*
-     * Send first byte
-     */
+    ssync();
+    // Send first byte
     *pTWI_XMT_DATA8 = p_data[0];
-    *pTWI_MASTER_CTL = TWI_COUNT(write_cnt) | MEN | (rstart ? RSTART : 0);
-    asm("ssync;");
+    *pTWI_MASTER_CTL = TWI_COUNT(write_cnt) | FAST | MEN | (rstart != TWI_STOP ? RSTART : 0);
+}
 
-    for (l_idx = 1; l_idx < write_cnt; l_idx++) {
-        while(((*pTWI_INT_STAT & MERR) == 0U) && (*pTWI_FIFO_STAT == XMTSTAT)) {
-            asm("ssync;");
-        }
-        *pTWI_XMT_DATA8 = p_data[l_idx];
-        asm("ssync;");
-    }
+void twi_master_read(uint8_t slave_addr, int32_t rstart, uint8_t* p_data, int32_t read_cnt)
+{
+    if(read_cnt <= 0) return;
 
-    /*
-     * 転送終了まで待機
-     */
-    while ((*pTWI_INT_STAT & MCOMP) == 0U) {
-        asm("ssync;");
-    }
+    sf_twi_xfer_param.state    = TWI_STATE_XFER;
+    sf_twi_xfer_param.xfer_dir = 0;
+    sf_twi_xfer_param.p_data   = p_data;
+    sf_twi_xfer_param.count    = read_cnt;
 
-    if ((*pTWI_INT_STAT & MERR) == 0U) {
-        return NO_ERROR;
-    } else {
-        return TWI_ERROR_NAK;
-    }
+    *pTWI_CONTROL |= TWI_ENA;
+    ssync();
+    *pTWI_INT_STAT = MCOMP | MERR | XMTSERV | RCVSERV;
+    *pTWI_MASTER_STAT = BUFWRERR | BUFRDERR | LOSTARB | ANAK | DNAK;
+    *pTWI_MASTER_ADDR = slave_addr;
+    ssync();
+    *pTWI_MASTER_CTL = TWI_COUNT(read_cnt) | FAST | MDIR | MEN | (rstart != TWI_STOP ? RSTART : 0);
 }
 
+int32_t twi_master_xfer_state(void)
+{
+    return sf_twi_xfer_param.state;
+}
+
+__attribute__((interrupt_handler)) void s_bfin_twi_isr(void)
+{
+    uint16_t l_twi_stat = *pTWI_INT_STAT;
+    *pTWI_INT_STAT = l_twi_stat;
+    ssync();
+
+    if((l_twi_stat & MERR) != 0)
+    {
+        sf_twi_xfer_param.state = TWI_STATE_ERROR;
+        *pTWI_CONTROL &= ~TWI_ENA;
+    }
+    else if(sf_twi_xfer_param.state != TWI_STATE_ERROR)
+    {
+        if((l_twi_stat & MCOMP) != 0)
+        {
+            sf_twi_xfer_param.state = TWI_STATE_COMP;
+            *pTWI_CONTROL &= ~TWI_ENA;
+        }
+        else
+        {
+            if(0 == sf_twi_xfer_param.xfer_dir)
+            {
+                while((sf_twi_xfer_param.count > 0) && ((*pTWI_FIFO_STAT & RCVSTAT) != 0))
+                {
+                    *sf_twi_xfer_param.p_data = *pTWI_RCV_DATA8;
+                    sf_twi_xfer_param.p_data++;
+                    sf_twi_xfer_param.count--;
+                    ssync();
+                }
+            }
+            else
+            {
+                while((sf_twi_xfer_param.count > 0) && ((*pTWI_FIFO_STAT & XMTSTAT) != XMTSTAT))
+                {
+                    *pTWI_XMT_DATA8 = *sf_twi_xfer_param.p_data;
+                    sf_twi_xfer_param.p_data++;
+                    sf_twi_xfer_param.count--;
+                    ssync();
+                }
+            }
+        }
+    }
+}
index 5850528..a217a8c 100644 (file)
 #ifndef TWI_H
 #define TWI_H
 
-#include <stdint.h>
+#define TWI_STATE_ERROR    (-1)
+#define TWI_STATE_XFER     (0)
+#define TWI_STATE_COMP     (1)
 
-/* TWI用戻り値 */
-#define NO_ERROR        (0)
-#define TWI_ERROR_NAK   (-1)
+#define TWI_STOP           (0)
+#define TWI_RSTART         (1)
 
-/* twi_master_writeのrstart引数用定義 */
-#define TWI_STOP        (0)
-#define TWI_RSTART      (1)
-
-/**
- * @brief TWI(I2C)を初期化する。
- */
 void twi_init(void);
-
-/**
- * @brief TWI(I2C)バスに書き込む。
- *
- * @param slave_addr スレーブアドレス。
- * @param rstart スタートコンディション。
- * @param p_data データ。
- * @param write_cnt 書き込むデータバイト数。
- *
- * @retval NO_ERROR エラーなし。
- * @retval TWI_ERROR_NAK エラー。
- */
-int32_t twi_master_write(uint8_t slave_addr, int32_t rstart, const uint8_t* p_data, int32_t write_cnt);
+void twi_master_write(uint8_t slave_addr, int32_t rstart, const uint8_t* p_data, int32_t write_cnt);
+void twi_master_read(uint8_t slave_addr, int32_t rstart, uint8_t* p_data, int32_t read_cnt);
+int32_t twi_master_xfer_state(void);
 
 #endif
 
diff --git a/firm/bare_metal/uart.c b/firm/bare_metal/uart.c
new file mode 100644 (file)
index 0000000..6315b65
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * @file uart.c
+ * @author Copyright(C) 2012 Shinichiro Nakamura
+ * @brief BlueTank ACB-BF592 Application Sample Codes.
+ */
+
+/*
+ * ===============================================================
+ *  BlueTank
+ * ===============================================================
+ * Copyright (c) 2012 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#include <cdefBF592-A.h>
+#include <builtins.h>
+#include "uart.h"
+
+/* システムクロック(98.304MHz) */
+#define SCLOCK_HZ       (98304000)
+
+/* ボーレート(115200bps) */
+#define UART0_BAUDRATE  (115200)
+
+/* UART0_DLL/UART0_DLHの設定値 */
+#define UART0_DIVISOR   (SCLOCK_HZ / 16 / UART0_BAUDRATE)
+
+void uart_init(void)
+{
+    /* UARTイネーブル */
+    *pUART0_GCTL = 1;
+
+    /* UART分周比の設定 */
+    *pUART0_LCR |= DLAB;
+    *pUART0_DLL = UART0_DIVISOR & 0xFF;
+    *pUART0_DLH = UART0_DIVISOR >> 8;
+    *pUART0_LCR &= ~DLAB;
+
+    /* UARTモード設定 パリティ無し 8bit 1ストップビット */
+    *pUART0_LCR = WLS(8);
+
+    /* UART割込み禁止 */
+    *pUART0_IER = 0;
+
+    /* PF11/PF12ピンをUARTに割り振る */
+    *pPORTF_MUX &= ~(PF11 | PF12);  /* PF11,PF12を0にする */
+    *pPORTF_FER |= PF11 | PF12;     /* PF11,PF12をUART0に割り振る */
+}
+
+void uart_putc(char ch)
+{
+    /* UART0 LSRのTHREが1になるまで待つ。1ならば送信レジスタ空き */
+    while (0 == (*pUART0_LSR & THRE)) {
+        ssync();
+    }
+    *pUART0_THR = ch;   /* 一文字送信 */
+    ssync();
+}
+
diff --git a/firm/bare_metal/uart.h b/firm/bare_metal/uart.h
new file mode 100644 (file)
index 0000000..3591287
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * @file uart.h
+ * @author Copyright(C) 2012 Shinichiro Nakamura
+ * @brief BlueTank ACB-BF592 Application Sample Codes.
+ */
+
+/*
+ * ===============================================================
+ *  BlueTank
+ * ===============================================================
+ * Copyright (c) 2012 Shinichiro Nakamura
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ * ===============================================================
+ */
+
+#ifndef UART_H
+#define UART_H
+
+void uart_init(void);
+void uart_putc(char ch);
+
+#endif
+
index b26d4fd..da04543 100644 (file)
@@ -45,6 +45,7 @@
 #include "at24c.h"
 #include "uzume.h"
 #include "mmc.h"
+#include "uart.h"
 
 #define SCLOCK_HZ           (100000000) /**< システムクロック(100MHz) */
 #define DMA_SAMPLE_SIZE     (256)       /**< 1回のサンプルサイズ */
@@ -106,6 +107,8 @@ static void vdsp_register_handler(interrupt_kind kind, ex_handler_fn_gcc fn)
 
 void uzume_init(UZUME *p, void *user_data)
 {
+    uint8_t c;
+    bool sdc_detected;
     FATFS fatfs;
 #if 0
     DIR dir;
@@ -121,6 +124,8 @@ void uzume_init(UZUME *p, void *user_data)
      */
     setup_pll(16, 4);
 
+    uart_init();
+
     /*
      * LEDを初期化する。
      */
@@ -152,13 +157,11 @@ void uzume_init(UZUME *p, void *user_data)
     /*
      * SDカードをマウントする。
      */
+    pf_mount(&fatfs);
     if (MMC_DETECT()) {
-        if (pf_mount(&fatfs) != FR_OK) {
-            lcd_goto(0, 0);
-            lcd_puts("SDC FAIL");
-            while (1) {
-            }
-        }
+        sdc_detected = true;
+    } else {
+        sdc_detected = false;
     }
 
     /*
@@ -236,12 +239,33 @@ void uzume_init(UZUME *p, void *user_data)
     led_write(LedTargetR, 0);
     led_write(LedTargetG, 1);
     lcd_goto(0, 1);
-    lcd_puts("InitDone");
+    if (sdc_detected) {
+        lcd_puts("SDC: Yes");
+    } else {
+        lcd_puts("SDC: No ");
+    }
 
     /*
      * ミュートを解除する。
      */
     ssm2603_mute(false);
+
+    /*
+     * AT24C test...
+     */
+    at24c_init();
+
+    lcd_goto(0, 1); lcd_puts("write.1."); at24c_write(0x00, 'a');
+    lcd_goto(0, 1); lcd_puts("write.2."); at24c_write(0x01, 'b');
+    lcd_goto(0, 1); lcd_puts("write.3."); at24c_write(0x02, 'c');
+
+    lcd_goto(0, 1);
+    lcd_puts("read.1..");
+    at24c_read(0x00, &c); lcd_goto(0, 1); lcd_putc(c);
+    lcd_puts("read.2..");
+    at24c_read(0x01, &c); lcd_goto(1, 1); lcd_putc(c);
+    lcd_puts("read.3..");
+    at24c_read(0x02, &c); lcd_goto(2, 1); lcd_putc(c);
 }
 
 void uzume_set_effect(UZUME *p, UZUME_EFFECT_FUNC effect)