OSDN Git Service

Separated the TWI codes.
authorShinichiro Nakamura <shinta.main.jp@gmail.com>
Thu, 9 Aug 2012 18:12:28 +0000 (03:12 +0900)
committerShinichiro Nakamura <shinta.main.jp@gmail.com>
Thu, 9 Aug 2012 18:12:28 +0000 (03:12 +0900)
firm/bare_metal/Makefile
firm/bare_metal/main.c
firm/bare_metal/twi.c [new file with mode: 0644]
firm/bare_metal/twi.h [new file with mode: 0644]

index 23dd611..ac35b81 100644 (file)
@@ -6,7 +6,7 @@ PROJECT = bluetank
 #
 # Source files and search directories
 #
-CSRC   += lcd.c led.c main.c mmc.c pff.c
+CSRC   += lcd.c led.c main.c mmc.c pff.c twi.c
 ASRC   +=
 VPATH   =
 
index 67c2399..d64307d 100644 (file)
@@ -1,23 +1,7 @@
-/*\r
- * ACB-BF592 UMB-SSM2603 トークスルーコード例\r
- *\r
- * Original : Copyright(C) 2012 Kaneko System Co., Ltd.\r
- *\r
- * Modified : Copyright(C) 2012 CuBeatSystems\r
- *            - Changed the SPORT port configuration to SPORT 0 from SPORT 1\r
- *            - Changed the DMA for SPORT to DMA1 from DMA3.\r
- *            - Changed the DMA for SPORT to DMA2 from DMA4.\r
- *            - Added the control for the mute pin.\r
- *            - Modified interrupt function codes for gcc.\r
- *              The original code uses VisualDSP++.\r
- *\r
- * Last Update: 2012/07/07\r
- *\r
- * 【ご注意】\r
- * ・どなたでも自由に改変して使用することができます。\r
- * ・このソフトウェアは無保証です。このファイルに記載されている情報・コードを\r
- *   使用する場合は、ユーザの責任において行ってください。これらの使用に\r
- *   起因し、ユーザまたは第三者に生じた損害に関し、当社は一切の責任を負いません。\r
+/**\r
+ * @file main.c\r
+ * @brief BlueTank ACB-BF592 Application Sample Codes.\r
+ * @author Copyright(C) 2012 Shinichiro Nakamura\r
  */\r
 \r
 #include <cdefBF592-A.h>\r
 #include "lcd.h"\r
 #include "led.h"\r
 #include "pff.h"\r
+#include "twi.h"\r
 \r
 /* システムクロック(100MHz) */\r
 #define SCLOCK_HZ   (100000000)\r
 \r
-#define TWI_COUNT(x) (DCNT & ((x) << 6))\r
-/* TWI用戻り値 */\r
-#define NO_ERROR        (0)\r
-#define TWI_ERROR_NAK   (-1)\r
-/* s_twi_master_writeのrstart引数用定義 */\r
-#define TWI_STOP        (0)\r
-#define TWI_RSTART      (1)\r
-\r
 /* SSM2603のI2Cデバイスアドレス */\r
 #define TWI_DEVICE_ADDR (0x1A)\r
 \r
 #define NUM_SAMPLES     (256)\r
 \r
 /* SPORT RX DMA割り込みのプロトタイプ宣言 */\r
-void s_sport_rx_isr() __attribute__((interrupt_handler));\r
+void sport_rx_isr() __attribute__((interrupt_handler));\r
 /* オーディオ処理用関数 */\r
-void s_audio_process(const int32_t* src, int32_t* des, int32_t count);\r
-\r
-/* TWI(I2C)初期化用関数 */\r
-void s_twi_init(void);\r
-/* TWI(I2C)データ送信用関数 */\r
-int32_t s_twi_master_write(uint8_t slave_addr, int32_t rstart, const uint8_t* p_data, int32_t write_cnt);\r
+void audio_effect(const int32_t* src, int32_t* des, int32_t count);\r
 \r
 /* SPORT受信バッファ(ダブルバッファ) */\r
-static int32_t sf_sport_rxbuf[2][NUM_SAMPLES];\r
+static int32_t sport_buffer_rx[2][NUM_SAMPLES];\r
 /* SPORT受信バッファ(ダブルバッファ) */\r
-static int32_t sf_sport_txbuf[2][NUM_SAMPLES];\r
+static int32_t sport_buffer_tx[2][NUM_SAMPLES];\r
 /* DMAがどのバッファ使用をしているか */\r
-static volatile int32_t sf_sport_use_bufidx;\r
-\r
+static volatile int32_t bufidx_dma_target;\r
 /* データ転送完了フラグ */\r
-static volatile int32_t sf_data_incoming;\r
+static volatile int32_t data_ready;\r
 \r
 int iii;\r
 \r
 /* SSM2603 TWI初期化データ列 */\r
-static const uint8_t sf_audio_init_data[] =\r
+static const uint8_t ssm2603_initdata[] =\r
 {\r
     (0x0F << 1) | 0, 0x00,\r
     (0x00 << 1) | 1, 0x17,\r
@@ -82,7 +53,7 @@ static const uint8_t sf_audio_init_data[] =
     (0x09 << 1) | 0, 0x01,\r
 };\r
 \r
-static void s_bfin_clk_pll_set(uint8_t mul_val, uint8_t div_val)\r
+static void setup_pll(uint8_t mul_val, uint8_t div_val)\r
 {\r
     *pSIC_IWR = IWR_ENABLE(0);  /* PLLのみIWRを許す */\r
     *pPLL_DIV = div_val;\r
@@ -92,45 +63,48 @@ static void s_bfin_clk_pll_set(uint8_t mul_val, uint8_t div_val)
 }\r
 \r
 /* SPORT RX DMA割り込みハンドラ */\r
-__attribute__((interrupt_handler)) void s_sport_rx_isr()\r
+__attribute__((interrupt_handler)) void sport_rx_isr()\r
 {\r
     *pDMA1_IRQ_STATUS = DMA_DONE;\r
     asm("ssync;");\r
     /* オーディオコーデックからデータ到着 */\r
-    sf_data_incoming = 1;\r
+    data_ready = 1;\r
     /* DMAが使用するバッファを変更 */\r
-    sf_sport_use_bufidx = (sf_sport_use_bufidx ^ 1) & 1;\r
+    bufidx_dma_target = (bufidx_dma_target ^ 1) & 1;\r
 }\r
 \r
 int main(void)\r
 {\r
-    uint32_t l_lc, l_ld;\r
-    int32_t  l_dmabuf_idx;\r
+    uint32_t i, j;\r
+    int32_t bufidx_dma_done;\r
     FATFS fatfs;\r
     DIR dir;\r
     FILINFO finfo;\r
 \r
-    /* PLLを設定 */\r
-    s_bfin_clk_pll_set(16, 4);\r
-\r
-    led_init();\r
+    /*\r
+     * PLLを設定する。\r
+     */\r
+    setup_pll(16, 4);\r
 \r
     /*\r
-     * LED: Wait...\r
+     * LEDを初期化する。\r
      */\r
+    led_init();\r
     led_write(LedTargetR, 1);\r
     led_write(LedTargetG, 0);\r
 \r
+    /*\r
+     * LCDを初期化する。\r
+     */\r
     lcd_init();\r
     lcd_clear();\r
-\r
     lcd_goto(0, 0);\r
     lcd_puts("BlueTank");\r
     lcd_goto(0, 1);\r
     lcd_puts("Init....");\r
 \r
     /*\r
-     * PFF test\r
+     * SDカードをマウントする。\r
      */\r
     if (pf_mount(&fatfs) == FR_OK) {\r
         lcd_goto(0, 0);\r
@@ -140,24 +114,34 @@ int main(void)
         lcd_puts("MT: FAIL");\r
     }\r
 \r
-    /* バッファクリア */\r
-    memset(sf_sport_rxbuf, 0 , sizeof(sf_sport_rxbuf));\r
-    memset(sf_sport_txbuf, 0 , sizeof(sf_sport_txbuf));\r
-    sf_sport_use_bufidx = 0;\r
-    sf_data_incoming = 0;\r
+    /*\r
+     * バッファをクリアする。\r
+     */\r
+    memset(sport_buffer_rx, 0 , sizeof(sport_buffer_rx));\r
+    memset(sport_buffer_tx, 0 , sizeof(sport_buffer_tx));\r
+    bufidx_dma_target = 0;\r
+    data_ready = 0;\r
 \r
-    /* ポートの設定 */\r
+    /*\r
+     * ポートの設定\r
+     */\r
     *pPORTG_MUX &= ~(PG1 | PG2 | PG3 | PG5 | PG6 | PG7);\r
     *pPORTG_FER |= (PG1 | PG2 | PG3 | PG5 | PG6 | PG7);\r
 \r
-    /* TWI初期化 */\r
-    s_twi_init();\r
-    /* SSM2603初期化 */\r
-    for (l_lc = 0; l_lc < sizeof(sf_audio_init_data); l_lc += 2) {\r
-        /* SSM2603レジスタ設定 */\r
-        s_twi_master_write(TWI_DEVICE_ADDR, TWI_STOP, &sf_audio_init_data[l_lc], 2);\r
-        /* STOP CONDITIONから600ns以上空ける */\r
-        for (l_ld = 0; l_ld < 300; l_ld++) {\r
+    /*\r
+     * TWI初期化\r
+     */\r
+    twi_init();\r
+\r
+    /*\r
+     * SSM2603初期化\r
+     */\r
+    for (i = 0; i < sizeof(ssm2603_initdata); i+=2) {\r
+        twi_master_write(TWI_DEVICE_ADDR, TWI_STOP, &ssm2603_initdata[i], 2);\r
+        /*\r
+         * STOP CONDITIONから600ns以上空ける\r
+         */\r
+        for (j = 0; j < 300; j++) {\r
             asm("ssync;");\r
         }\r
     }\r
@@ -165,7 +149,7 @@ int main(void)
     /*\r
      * 割り込みハンドラをIVG9に登録\r
      */\r
-    *pEVT9 = s_sport_rx_isr;\r
+    *pEVT9 = sport_rx_isr;\r
     asm("ssync;");\r
     asm volatile ("cli %0; bitset (%0, 9); sti %0; csync;": "+d"(iii)); // set IMASK bit\r
     asm("ssync;");\r
@@ -193,7 +177,7 @@ int main(void)
      */\r
     *pDMA1_PERIPHERAL_MAP = 0x1000;\r
     *pDMA1_CONFIG = FLOW_AUTO | DI_EN | DI_SEL | DMA2D | WDSIZE_32 | WNR;\r
-    *pDMA1_START_ADDR = sf_sport_rxbuf;\r
+    *pDMA1_START_ADDR = sport_buffer_rx;\r
     *pDMA1_X_COUNT = NUM_SAMPLES;\r
     *pDMA1_X_MODIFY = sizeof(int32_t);\r
     *pDMA1_Y_COUNT = 2;\r
@@ -204,7 +188,7 @@ int main(void)
      */\r
     *pDMA2_PERIPHERAL_MAP = 0x2000;\r
     *pDMA2_CONFIG = FLOW_AUTO | DMA2D | WDSIZE_32;\r
-    *pDMA2_START_ADDR = sf_sport_txbuf;\r
+    *pDMA2_START_ADDR = sport_buffer_tx;\r
     *pDMA2_X_COUNT = NUM_SAMPLES;\r
     *pDMA2_X_MODIFY = sizeof(int32_t);\r
     *pDMA2_Y_COUNT = 2;\r
@@ -226,33 +210,37 @@ int main(void)
     *pSPORT0_RCR1 |= RSPEN;\r
     asm("ssync;");\r
 \r
-    lcd_goto(0, 1);\r
-    lcd_puts("InitDone");\r
-\r
     /*\r
-     * PG13(MUTE#)ã\82\92å\87ºå\8a\9bã\83\94ã\83³ã\81«è¨­å®\9aã\81\97ã\81¾ã\81\99\r
+     * PG13(MUTE#)ã\82\92å\87ºå\8a\9bã\83\94ã\83³ã\81«è¨­å®\9aã\81\99ã\82\8bã\80\82\r
      */\r
     *pPORTGIO_DIR |= PG13;\r
 \r
     /*\r
-     * PG13(MUTE#)ã\82\92'H'å\87ºå\8a\9bã\81«è¨­å®\9aã\81\97ã\81¾ã\81\99\r
+     * PG13(MUTE#)ã\82\92'H'å\87ºå\8a\9bã\81«è¨­å®\9aã\81\99ã\82\8bã\80\82\r
      */\r
     *pPORTGIO_SET = PG13;\r
 \r
     /*\r
-     * LED: Go!\r
+     * 初期化の完了をユーザに通知する。\r
      */\r
     led_write(LedTargetR, 0);\r
     led_write(LedTargetG, 1);\r
+    lcd_goto(0, 1);\r
+    lcd_puts("InitDone");\r
 \r
     while (1) {\r
         asm("idle;");\r
-        if (0 != sf_data_incoming) {\r
-            /* フラグクリア */\r
-            sf_data_incoming = 0;\r
-            /* 使用してよいバッファを取得 */\r
-            l_dmabuf_idx = sf_sport_use_bufidx ^ 1;\r
-            s_audio_process(sf_sport_rxbuf[l_dmabuf_idx], sf_sport_txbuf[l_dmabuf_idx], NUM_SAMPLES);\r
+        if (0 != data_ready) {\r
+            /*\r
+             * フラグをクリアする。\r
+             */\r
+            data_ready = 0;\r
+\r
+            /*\r
+             * DMAが完了したバッファを使用してオーディオ処理を行なう。\r
+             */\r
+            bufidx_dma_done = bufidx_dma_target ^ 1;\r
+            audio_effect(sport_buffer_rx[bufidx_dma_done], sport_buffer_tx[bufidx_dma_done], NUM_SAMPLES);\r
         }\r
     }\r
 \r
@@ -265,76 +253,8 @@ int main(void)
  * @param src 処理元バッファ。\r
  * @param des 処理後バッファ。\r
  */\r
-void s_audio_process(const int32_t *src, int32_t *des, int32_t count)\r
+void audio_effect(const int32_t *src, int32_t *des, int32_t count)\r
 {\r
     memcpy(des, src, sizeof(int32_t) * count);\r
 }\r
 \r
-/**\r
- * @brief TWI(I2C)を初期化する。\r
- */\r
-void s_twi_init(void)\r
-{\r
-    *pTWI_CONTROL = 0;\r
-    asm("ssync;");\r
-    *pTWI_CONTROL = TWI_ENA | 10U;\r
-    *pTWI_CLKDIV  = CLKHI(50) | CLKLOW(50);\r
-    *pTWI_INT_MASK = RCVSERV | XMTSERV | MERR | MCOMP;\r
-    *pTWI_INT_STAT = *pTWI_INT_STAT;\r
-    *pTWI_FIFO_CTL = XMTFLUSH | RCVFLUSH;\r
-    asm("ssync;");\r
-}\r
-\r
-/**\r
- * @brief TWI(I2C)バスに書き込む。\r
- *\r
- * @param slave_addr スレーブアドレス。\r
- * @param rstart スタートコンディション。\r
- * @param p_data データ。\r
- * @param write_cnt 書き込むデータバイト数。\r
- *\r
- * @retval NO_ERROR エラーなし。\r
- * @retval TWI_ERROR_NAK エラー。\r
- */\r
-int32_t s_twi_master_write(uint8_t slave_addr, int32_t rstart, const uint8_t* p_data, int32_t write_cnt)\r
-{\r
-    int32_t l_idx;\r
-\r
-    if (write_cnt <= 0) {\r
-        return NO_ERROR;\r
-    }\r
-\r
-    *pTWI_FIFO_CTL = 0;\r
-    *pTWI_INT_STAT = *pTWI_INT_STAT;\r
-    *pTWI_MASTER_STAT = BUFWRERR | BUFRDERR | LOSTARB | ANAK | DNAK;\r
-    *pTWI_MASTER_ADDR = slave_addr;\r
-\r
-    /*\r
-     * Send first byte\r
-     */\r
-    *pTWI_XMT_DATA8 = p_data[0];\r
-    *pTWI_MASTER_CTL = TWI_COUNT(write_cnt) | MEN | (rstart ? RSTART : 0);\r
-    asm("ssync;");\r
-\r
-    for (l_idx = 1; l_idx < write_cnt; l_idx++) {\r
-        while(((*pTWI_INT_STAT & MERR) == 0U) && (*pTWI_FIFO_STAT == XMTSTAT)) {\r
-            asm("ssync;");\r
-        }\r
-        *pTWI_XMT_DATA8 = p_data[l_idx];\r
-        asm("ssync;");\r
-    }\r
-\r
-    /*\r
-     * 転送終了まで待機\r
-     */\r
-    while ((*pTWI_INT_STAT & MCOMP) == 0U) {\r
-        asm("ssync;");\r
-    }\r
-\r
-    if ((*pTWI_INT_STAT & MERR) == 0U) {\r
-        return NO_ERROR;\r
-    } else {\r
-        return TWI_ERROR_NAK;\r
-    }\r
-}\r
-\r
diff --git a/firm/bare_metal/twi.c b/firm/bare_metal/twi.c
new file mode 100644 (file)
index 0000000..9b07973
--- /dev/null
@@ -0,0 +1,74 @@
+
+#include "twi.h"
+#include <cdefBF592-A.h>
+
+#define TWI_COUNT(x) (DCNT & ((x) << 6))
+
+/**
+ * @brief TWI(I2C)を初期化する。
+ */
+void twi_init(void)
+{
+    *pTWI_CONTROL = 0;
+    asm("ssync;");
+    *pTWI_CONTROL = TWI_ENA | 10U;
+    *pTWI_CLKDIV  = CLKHI(50) | CLKLOW(50);
+    *pTWI_INT_MASK = RCVSERV | XMTSERV | MERR | MCOMP;
+    *pTWI_INT_STAT = *pTWI_INT_STAT;
+    *pTWI_FIFO_CTL = XMTFLUSH | RCVFLUSH;
+    asm("ssync;");
+}
+
+/**
+ * @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)
+{
+    int32_t l_idx;
+
+    if (write_cnt <= 0) {
+        return NO_ERROR;
+    }
+
+    *pTWI_FIFO_CTL = 0;
+    *pTWI_INT_STAT = *pTWI_INT_STAT;
+    *pTWI_MASTER_STAT = BUFWRERR | BUFRDERR | LOSTARB | ANAK | DNAK;
+    *pTWI_MASTER_ADDR = slave_addr;
+
+    /*
+     * Send first byte
+     */
+    *pTWI_XMT_DATA8 = p_data[0];
+    *pTWI_MASTER_CTL = TWI_COUNT(write_cnt) | MEN | (rstart ? RSTART : 0);
+    asm("ssync;");
+
+    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;");
+    }
+
+    /*
+     * 転送終了まで待機
+     */
+    while ((*pTWI_INT_STAT & MCOMP) == 0U) {
+        asm("ssync;");
+    }
+
+    if ((*pTWI_INT_STAT & MERR) == 0U) {
+        return NO_ERROR;
+    } else {
+        return TWI_ERROR_NAK;
+    }
+}
+
diff --git a/firm/bare_metal/twi.h b/firm/bare_metal/twi.h
new file mode 100644 (file)
index 0000000..8c61466
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef TWI_H
+#define TWI_H
+
+#include <stdint.h>
+
+/* TWI用戻り値 */
+#define NO_ERROR        (0)
+#define TWI_ERROR_NAK   (-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);
+
+#endif
+