yoneda 1 рік тому
батько
коміт
db6e655f01
4 змінених файлів з 68 додано та 34 видалено
  1. 7 10
      ADRS2040U_i2c.h
  2. 3 0
      CMakeLists.txt
  3. 11 11
      adc_driver.hpp
  4. 47 13
      main.cpp

+ 7 - 10
ADRS2040U_i2c.h

@@ -17,17 +17,14 @@
 #define GPIO_SDA0 0
 #define GPIO_SCK0 1
 
-
-// I2Cコマンド列挙
+// I2Cコマンド
 enum ADRS2040_CMD {
-    ADRS2040_CMD_INVALID,
-    ADRS2040_CMD_ADC_START,
-    ADRS2040_CMD_ADC_STOP, 
-    ADRS2040_CMD_SELECT_INPUT,
-    ADRS2040_CMD_SET_RATE,
-    ADRS2040_CMD_GET_INPUT,
-    ADRS2040_CMD_GET_RATE,
-    ADRS2040_CMD_GET_COUNT,
+    ADRS2040_CMD_INVALID,       // 無効
+    ADRS2040_CMD_ADC_START,     // ADC割り込み開始
+    ADRS2040_CMD_ADC_STOP,      // ADC割り込み停止
+    ADRS2040_CMD_SET_RATE,      // サンプリングレート設定
+    ADRS2040_CMD_GET_COUNT,     // バッファデータ数
+    ADRS2040_CMD_GET_VALUE,      // ADCデータ読み取り
 };
 
 

+ 3 - 0
CMakeLists.txt

@@ -26,5 +26,8 @@ target_link_libraries(${PROJECT_NAME}
 	pico_multicore
 )
 
+pico_enable_stdio_usb(${PROJECT_NAME} 1)
+pico_enable_stdio_uart(${PROJECT_NAME} 0)
+
 # create map/bin/hex/uf2 file in addition to ELF.
 pico_add_extra_outputs(${PROJECT_NAME})

+ 11 - 11
adc_driver.hpp

@@ -7,6 +7,7 @@
 
 #define ADC_BUFF_SIZE   0x100
 
+// MUTEX
 auto_init_mutex(adcbuff_mutex);
 
 static volatile int read_p;
@@ -25,12 +26,10 @@ static void adc_interrupt(void)
 
 class ADC_Driver {
     private:
-
-        int sample_rate = 1000;
-        uint32_t adc_clk;
-
-        uint8_t adc_pin;
-        uint8_t adc_channel;
+        int sample_rate = 1000;     // サンプリングレート
+        uint32_t adc_clk;           // ADCクロック
+        uint8_t adc_pin;            // 使用するADCピン番号
+        uint8_t adc_channel;        // ADCチャンネル番号
 
     public:
         ADC_Driver(uint8_t p = 26, uint8_t c = 0) : adc_pin(p),  adc_channel(c) 
@@ -50,7 +49,6 @@ class ADC_Driver {
             run(false);
         };
 
-
         int get_sample_rate(void)
         {
             return sample_rate;
@@ -69,18 +67,17 @@ class ADC_Driver {
 
         int get_value(void)
         {
-            int wp;
-            int rv;
+            int wp, rv;
 
             mutex_enter_blocking(&adcbuff_mutex);
             wp = write_p;
-            mutex_exit(&adcbuff_mutex);
             if(read_p != wp) {
                 rv = adc_buffer[read_p];
                 read_p = (read_p + 1) & (ADC_BUFF_SIZE - 1);
             }
             else
                 rv = -1;
+            mutex_exit(&adcbuff_mutex);
 
             return rv;
         };
@@ -99,6 +96,9 @@ class ADC_Driver {
         {
             adc_irq_set_enabled(r);
             adc_run(r);
-        };
 
+            if(r == false) {
+                read_p = write_p = 0;
+            }
+        };
 };

+ 47 - 13
main.cpp

@@ -13,32 +13,67 @@
 #include "ADRS2040U_i2c.h"
 #include "adc_driver.hpp"
 
+// ADCドライバ
 ADC_Driver adcd;
 
+typedef union {
+    uint16_t d;
+    uint8_t  b[2];
+} WORD_t;
+
+
 static void i2c_slave_handler(i2c_inst_t *i2c, i2c_slave_event_t event)
 {
     static uint8_t ADRS2040U_cmd = ADRS2040_CMD_INVALID;
-    uint8_t raw_data;
 
     switch(event) {
+        // I2Cデータ受信
         case I2C_SLAVE_RECEIVE:
-            raw_data = i2c_read_byte_raw(i2c);
             if(ADRS2040U_cmd == ADRS2040_CMD_INVALID) {
-                ADRS2040U_cmd = raw_data;
+                ADRS2040U_cmd = i2c_read_byte_raw(i2c);
+            }
+            if(ADRS2040U_cmd == ADRS2040_CMD_ADC_START) {
+                adcd.run(true);
+                ADRS2040U_cmd = ADRS2040_CMD_INVALID;
+            }
+            else if(ADRS2040U_cmd == ADRS2040_CMD_ADC_STOP) {
+                adcd.run(false);
+                ADRS2040U_cmd = ADRS2040_CMD_INVALID;
+
+            }
+            else if(ADRS2040U_cmd == ADRS2040_CMD_SET_RATE) {
+                WORD_t rate;
+                i2c_read_raw_blocking(i2c, rate.b, sizeof(WORD_t));
+                DEBUG_PRINT("Rate = %d\n", rate.d * 10);
+                adcd.set_sample_rate(rate.d * 10);
+                ADRS2040U_cmd = ADRS2040_CMD_INVALID;
             }
             break;
-            
+        
+        // I2Cデータ要求
         case I2C_SLAVE_REQUEST:
-            DEBUG_PRINT("I2C_SLAVE_REQUEST\n");
+            WORD_t sdata;
+            sdata.d = 0;
+
             if(ADRS2040U_cmd == ADRS2040_CMD_GET_COUNT) {
-                i2c_write_byte_raw(i2c,adcd.count());
+                sdata.d = adcd.count();
             }
-            else
-                i2c_write_byte_raw(i2c, 0);
-            break;
+            else if(ADRS2040U_cmd == ADRS2040_CMD_GET_VALUE) {
+                int value = adcd.get_value();
 
-        case I2C_SLAVE_FINISH:
+                if( value >= 0) {
+                    sdata.d = value & 0xFFF;
+                }
+                else {
+                    sdata.d = 0xFFFF;
+                }
+            }
+            i2c_write_raw_blocking(i2c, sdata.b, sizeof(WORD_t));
             ADRS2040U_cmd = ADRS2040_CMD_INVALID;
+
+            break;
+        // STOP or RESTARTコンデション
+        case I2C_SLAVE_FINISH:
             break;
         
         default:
@@ -46,8 +81,6 @@ static void i2c_slave_handler(i2c_inst_t *i2c, i2c_slave_event_t event)
     }
 }
 
-
-
 void i2c_setup(void)
 {
     i2c_init(i2c0, 100 * 1000);
@@ -60,13 +93,14 @@ void i2c_setup(void)
     // プルアップする場合は以下の通り
 //   gpio_pull_up(GPIO_SDA0);
 //   gpio_pull_up(GPIO_SCK0);
-
+    // I2Cスレーブ初期化
     i2c_slave_init(i2c0, I2C0_SLAVE_ADDR, &i2c_slave_handler);
 }
 
 int main(void)
 {
     stdio_init_all();
+    i2c_setup();
     while (true)
     {
         ;