[[lbed]]

#contents

** ARM学習基板の実験に必要なクラス [#l5bca82e]

ARM学習基板の実験に必要なクラスについて、ページを分けて説明することにします。

*** DigitalInクラス [#h43a6707]
汎用入力クラスがまだ出来ていませんが、ほとんどDigitalOutクラスと同じなので
DigitalOutをDigitalInのサブクラスにすることにします。

まずは、mbedのDigitalInのAPIを以下のURLで調べます。
- http://mbed.org/handbook/DigitalIn


DigitalOut.cppをコピーして作りました。


クラス定義のDigitalIn.cppは、ほとんどDigitalOut.cppと同じです。
#pre{{
#include "platform.h"
#include "PinNames.h"
#include "AnalogIn.h"

#define ADC_CLK     4400000     /* set to 4.4Mhz */
AnalogIn::AnalogIn()
     : _channel(-1)
{
}

AnalogIn::AnalogIn(PinName pin, const char* name)
     : _channel(-1)
{
     setup(pin, name);
}

void AnalogIn::setup(PinName pin, const char* name)
{
     DigitalIn::setup(pin, name);
     /* Disable Power down bit to the ADC block. */
     LPC_SYSCON->PDRUNCFG &= ~(0x1<<4);
     /* Enable AHB clock to the ADC. */
     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<13);

     switch(pin) {
     case P0_11:
          _channel = 0; break;
     case P1_0:
          _channel = 1; break;
     case P1_1:
          _channel = 2; break;
     case P1_2:
          _channel = 3; break;
     case P1_3:
          _channel = 4; break;
     case P1_4:
          _channel = 5; break;
     case P1_10:
          _channel = 6; break;
     case P1_11:
          _channel = 7; break;
     }
     if (_channel >= 0) {
          *_io &= ~0x8F; /* ADC I/O config */
          if (_channel < 5)
               *_io |= 0x02;       /* ADC IN0~IN4 */
          else
               *_io |= 0x01;     /* ADC IN5~IN7 */

          LPC_ADC->CR = ( 0x01 << 0 ) |  /* SEL=1,select channel 0~7 on ADC0 */
            ( ( SystemCoreClock / ADC_CLK - 1 ) << 8 ) |  /* CLKDIV = Fpclk / 1000000 - 1 */
            ( 0 << 16 ) |           /* BURST = 0, no BURST, software controlled */
            ( 0 << 17 ) |            /* CLKS = 0, 11 clocks/10 bits */
            ( 0 << 24 ) |            /* START = 0 A/D conversion stops */
            ( 0 << 27 );          /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */
     }
}

float AnalogIn::read()
{
     return (float)read_u16()/(float)(0xFFFF);
}

unsigned short AnalogIn::read_u16()
{
     if (_channel >= 0) {
          unsigned int dat;

          LPC_ADC->CR = 0x01000f00 | (1 << _channel);
          do {
               dat = LPC_ADC->GDR;
          } while (!(dat & 0x80000000));
          return ((dat >> 6) &0x3ff);
     }
     else
          return 0;
}
}}


何かたくさんの定義をしたように思えるかも知れませんが、これによってDigitalOut.cppはとても簡単になります。
#pre{{
#include "platform.h"
#include "PinNames.h"
#include "DigitalOut.h"
#include "DigitalIn.h"

DigitalOut::DigitalOut()
{
}

DigitalOut::DigitalOut(PinName pin, const char* name)
{
     setup(pin, name);
}

void DigitalOut::setup(PinName pin, const char* name)
{
     DigitalIn::setup(pin, name);
     if (_gpio) {
          _gpio->DIR |= _mask;
     }
}
}}

** SerialCDCクラス [#p4e33d8c]
LPC1343は、USBのCDCクラスをサポートしているので、Serialクラスを拡張して
CDC対応のSerialCDCを作成しました。

ARMパーエフェクト学習基板の例題USBADCの例題のソースを使わせてもらいました。

*** SerialCDCのソース [#j91ae2e4]
SerialCDCのソースは、以下の様にしました。
#pre{{
#include "SerialCDC.h"
#include "PinNames.h"
#include "LPC13xx.h"
#include "_usb.h"
#include "_cdc_usbcfg.h"
#include "_usbhw.h"
#include "_usbcore.h"
#include "_cdc.h"
#include "_cdcuser.h"

SerialCDC::SerialCDC()
     : _tx(-1)
     , _rx(-1)
{
     setup(USBTX, USBRX, "default");
}

SerialCDC::SerialCDC(PinName tx, PinName rx, const char *name)
     : _tx(-1)
     , _rx(-1)
{
     setup(tx, rx, name);
}

void SerialCDC::setup(PinName tx, PinName rx, const char *name)
{
     _tx = tx;
     _rx = rx;
     _available = false;
     USBIOClkConfig();
     CDC_Init ();                         // CDC Initialization
     USB_Init();                          // USB Initialization
     USB_Connect(1);                       // USB Connect
     while (!USB_Configuration)
          continue;                         // wait until USB is configured
}

int SerialCDC::write(const char c) {
     unsigned int i;
     unsigned char cbuf;
     cbuf = c;
     while(!CDC_DepInEmpty)
          ;
     USB_WriteEP (CDC_DEP_IN, (unsigned char *)&cbuf, 1);
     for (i=0; i<10000; i++) {
          if (!CDC_DepInEmpty)
               break;
     }
     return (1);
}

int SerialCDC::read() {
     int          numAvailByte = 0;
     char     c;

     CheckSerialState();
     do {
          CDC_OutBufAvailChar (&numAvailByte);
          if (numAvailByte > 0) {
               int numBytesToRead = 1;
               int numBytesRead = CDC_RdOutBuf (&c, &numBytesToRead);
          }
     } while (numAvailByte <= 0);
     return (c);
}

void SerialCDC::CheckSerialState (void)
{
     unsigned short temp = CDC_GetSerialState();
     if (_serialState != temp) {
          _serialState = temp;
          CDC_NotificationIn();          // send SERIAL_STATE notification
     }
}
}}

*** なぞの現象 [#w0e92ea3]
最初、どうしてもUSBとして認識してくれないので、とても悩みまして、
例題のUSB関連のソースをMAINのソースと同じ場所に置いたところ、
うまく認識できるようになりました。

試行錯誤の結果、USBADCの例題のusbhw.cがアーカイブからのリンクでは
上手く動作しないことがわかり、暫定処置としてForSerialCDC_usbhw.cとして
LBED_LPC13xx_MAINのsrcに置くことにしました。
((変な構成で申し訳ありません。))


** コメント [#q56d2570]
#comment_kcaptcha


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc