忘備録-備忘録

技術的な備忘録

RX62NのUSB機能を使う その2

2016-01-28 17:39:01 | RX62N
前回「RX62NのUSB機能を使う」でRX62NのUSB機能を利用してCDCデバイスでパソコンと通信するプログラムを紹介しましたが、パソコン側からうまく認識されないことがあるようです。ルネサスエレクトロニクス社のサンプルを見ていたら「Renesas USB MCU USB Peripheral Communication Device Class Driver(PCDC)」を見つけました。とりあえず手持ちのe2studioに読み込み実行しようとしましたが、E1デバッガ経由で実行することができませんでした。
プロジェクトを新たに作成し、ソースコードをコピーし、一部手直ししたら動作しました。

修正したファイル

demo_src\r_usb_pcdc_descriptor.c
  1. /******************************************************************************
  2. User define macro definitions
  3. ******************************************************************************/
  4. /* bcdUSB */
  5. #define USB_BCDNUM (0x0200u)
  6. /* Release Number */
  7. #define USB_RELEASE (0x0200u)
  8. /* DCP max packet size */
  9. #define USB_DCPMAXP (64u)
  10. /* Configuration number */
  11. #define USB_CONFIGNUM (1u)
  12. /* Vendor ID */
  13. #define USB_VENDORID 0x045B
  14. /* Product ID */
  15. #define USB_PRODUCTID 0x2014
ベンダIDとプロダクトIDを手直しします。

r_config\r_bsp_config.h
使用しているMPUに合わせて変更(コメント通りに変更する)

RXマイコン基板(RX62N) | Renesas MCU Software Libraryの仮想COMポートファームウェアを試す 」にも書かれています。

手直ししたプロジェクト

改造しやすいように手直ししました。
USB機能を動作させるためには、一定間隔で次のプログラムを実行する必要があります。
  1.         usb_cdc_driver(); /* USB Driver(Peripheral CDC) */
  2.         switch( cdc_dev_info.state ) /* Check application state */
  3.         {
  4.         case STATE_DATA_TRANSFER: /* Data transfer state */
  5.             lcd_update = cdc_data_transfer();
  6.         break;
  7.         case STATE_ATTACH: /* Wait Connect(USB Configured) state */
  8.             lcd_update = cdc_connect_wait();
  9.         break;
  10.         case STATE_DETACH:
  11.             cdc_detach_device(); /* Detach process */
  12.         break;
  13.         default:
  14.         break;
  15.         }

変更したプロジェクト

さらに、printf,scanfなどの標準入出力関数が使えるように変更しました。
一定間隔でusb_cdc_manage()関数を呼び出せば動作します。時間待ちの時にもこの関数を呼び出してください。

標準入出力が使えるプロジェクト

usb_cdc_manage()関数をタイマ割り込みで動かせば、プログラムが簡単にできると思い、プログラムを変更しました。タイマ割り込みで呼び出しても、問題なく動作しています。初期化のためinitUSB_cdc()関数を呼び出すだけで、パソコンとUSB通信することが可能です。

タイマ割り込みを利用したプロジェクト

Windows用デバイスドライバ
Windows用のデバイスドライバはルネサスエレクトロニクスの「RX62Nグループ、RX621グループ USBペリフェラルCDCによるフラッシュブートローダ」サンプル内に「CDC_Demo_Win7.inf」ファイルが入っています。ベンダIDとプロダクトIDをRX62Nのプログラムに合わせて書き換えます。

  1. ;--------------------------------------------------------
  2. ;    Renesas
  3. ;
  4. ;    Communication Device Class
  5. ;    Virtual Serial Port
  6. ;    
  7. ;    20/12/04
  8. ;--------------------------------------------------------
  9. [Version]
  10. Signature="$Windows NT$"
  11. Class=Ports
  12. ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
  13. Provider=%MANUFACTURER%
  14. LayoutFile=layout.inf
  15. ;CatalogFile=%FILENAME%.cat
  16. DriverVer= 3/10/2010,1.1.2600.0
  17. [Manufacturer]
  18. %MANUFACTURER%=DeviceList,NTamd64
  19. [DestinationDirs]
  20. DefaultDestDir=12
  21. ;--------------------------------------------------------
  22. ; Windows XP Support
  23. ;--------------------------------------------------------
  24. [DriverInstall.nt]
  25. include=mdmcpq.inf
  26. CopyFiles=DriverCopyFiles.nt
  27. AddReg=DriverInstall.nt.AddReg
  28. [DriverCopyFiles.nt]
  29. usbser.sys,,,0x20
  30. [DriverInstall.nt.AddReg]
  31. HKR,,DevLoader,,*ntkern
  32. HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
  33. HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
  34. [DriverInstall.nt.Services]
  35. AddService=usbser, 0x00000002, DriverService.nt
  36. [DriverService.nt]
  37. DisplayName=%SERVICE%
  38. ServiceType=1
  39. StartType=3
  40. ErrorControl=1
  41. ServiceBinary=%12%\%DRIVERFILENAME%.sys
  42. ;--------------------------------------------------------
  43. ; Windows Support
  44. ;--------------------------------------------------------
  45. [DriverInstall.NTamd64]
  46. include=mdmcpq.inf
  47. CopyFiles=DriverCopyFiles.NTamd64
  48. AddReg=DriverInstall.NTamd64.AddReg
  49. [DriverCopyFiles.NTamd64]
  50. %DRIVERFILENAME%.sys,,,0x20
  51. [DriverInstall.NTamd64.AddReg]
  52. HKR,,DevLoader,,*ntkern
  53. HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
  54. HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
  55. [DriverInstall.NTamd64.Services]
  56. AddService=usbser, 0x00000002, DriverService.NTamd64
  57. [DriverService.NTamd64]
  58. DisplayName=%SERVICE%
  59. ServiceType=1
  60. StartType=3
  61. ErrorControl=1
  62. ServiceBinary=%12%\%DRIVERFILENAME%.sys
  63. ;**********************************************
  64. ; Please change to your company's information *
  65. ;**********************************************
  66. [SourceDisksFiles]
  67. [SourceDisksNames]
  68. [DeviceList]
  69. %DESCRIPTION%=DriverInstall, USB\VID_045B&PID_2014
  70. [DeviceList.NTamd64]
  71. %DESCRIPTION%=DriverInstall, USB\VID_045B&PID_2014
  72. ;**********************************************
  73. ; Please change to your company's information *
  74. ;**********************************************
  75. [Strings]
  76. FILENAME="Renesas_cdc"
  77. DRIVERFILENAME ="usbser"
  78. MANUFACTURER="Renesas"
  79. INSTDISK="USB2UART"
  80. DESCRIPTION="CDC USB Demonstration"
  81. SERVICE="CDC USB Demonstration Driver"

RX62NのUSB機能を使う

2015-12-06 21:29:51 | RX62N
RX62NのUSB機能を使用してRX62NをCDCデバイスにするプログラムです。基本となる部分はルネサスエレクトロニクスのサンプルプログラムを利用しました。
関数化してあるので簡単に使用することができます。

e2 studioのエクスポートしたプロジェクト

サンプルプログラム
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <machine.h>
  4. #include "iodefine.h"
  5. #include ".\USBStack\usb_hal.h"
  6. #include ".\USBStack\CDC\usb_cdc.h"
  7. void _INIT_IOLIB( void );    //プロトタイプ宣言
  8. int main(void)
  9. {
  10.     int data;
  11.     unsigned char c,buf[256];;
  12.     SYSTEM.SCKCR.BIT.ICK = 0x00;        //システムクロック x16 96MHz
  13.     SYSTEM.SCKCR.BIT.PCK = 0x01;        //周辺クロック   x4  48MHz
  14.     SYSTEM.SCKCR.BIT.BCK = 0x01;        //外部バスクロック x4  48MHz
  15.     /*Initialise the USB CDC Class*/
  16.     USBCDC_Init();
  17.     setpsw_i();                            //割込み許可 clrpsw_i()割込み禁止
  18.     _INIT_IOLIB();                        // printf(),scanf()の初期化
  19.     while(false == USBCDC_IsConnected());    //USB接続待ち
  20.     c = charget();        //ホストから1文字入力
  21.     printf("RX62N USB cdc test program.\n");
  22.     while(1)
  23.     {
  24.         c = charget();        //ホストから1文字入力
  25.         charput(c);        //ホストに1文字出力
  26.         printf("Input string:");
  27.         scanf("%s",buf);
  28.         printf("string: %s\n",buf);
  29.     }
  30. }

RX62NでFreeRTOSを動かす

2015-11-27 22:05:41 | RX62N
RX62N(インターフェス2011年5月号付録)でFreeRTOSを動かしました。環境はe2 studio, renesas RXCコンパイラです。
ここにプロジェクトをエクスポートしたものを置いておきます。
ファイル構成は次の通りです。
”FreeRTOS”以下のフォルダに必要なファイルをまとめました。
”FreeRTOS/renesas”以下にウィザードが自動生成するファイルをまとめておいてあります。
”port.c”にエラーが表示されているのはインラインアセンブラを使用しているためです。



フォルダを閉じるとユーザープログラムのみでシンプルになります。



プロジェクト作成時にはできるだけ自動生成するファイルを省き、それでも作成されるものは”FreeRTOS/renesas”のファイルと被るので削除します。



ここに”FreeRTOS”フォルダ以下のファイルをドラッグアンドドロップでコピーすればFreeRTOSのインストールは終了です。



4つのタスクが違う間隔で起動と待期を繰り返しながらLEDを点滅させるプログラムは次のようになります。

  1. #include <stdio.h>
  2. #include "FreeRTOS/renesas/iodefine.h"
  3. /* Kernel includes. */
  4. #include "FreeRTOS/FreeRTOS.h"
  5. #include "FreeRTOS/task.h"
  6. #include "FreeRTOS/queue.h"
  7. void vTask1(void *pvParameters)
  8. {
  9.     while(1) {
  10.         PORTD.DR.BIT.B1 = ~PORTD.DR.BIT.B1;
  11.         vTaskDelay(100/portTICK_PERIOD_MS);
  12.     }
  13. }
  14. void vTask2(void *pvParameters)
  15. {
  16.     while(1) {
  17.         PORTD.DR.BIT.B2 = ~PORTD.DR.BIT.B2;
  18.         vTaskDelay(200/portTICK_PERIOD_MS);
  19.     }
  20. }
  21. void vTask3(void *pvParameters)
  22. {
  23.     while(1) {
  24.         PORTD.DR.BIT.B3 = ~PORTD.DR.BIT.B3;
  25.         vTaskDelay(300/portTICK_PERIOD_MS);
  26.     }
  27. }
  28. void vTask4(void *pvParameters)
  29. {
  30.     while(1) {
  31.         PORTD.DR.BIT.B0 = ~PORTD.DR.BIT.B0;
  32.         vTaskDelay(400/portTICK_PERIOD_MS);
  33.     }
  34. }
  35. void main(void)
  36. {
  37.     /* Renesas provided CPU configuration routine. The clocks are configured in
  38.     here. */
  39.     /* Turn all LEDs off. */
  40.     PORTD.DDR.BYTE = 0xFF;    //ポートC出力
  41.     PORTD.DR.BYTE = 0xFF;    //初期値
  42.     xTaskCreate(vTask1,"Task1",100,NULL,1,NULL);
  43.     xTaskCreate(vTask2,"Task2",100,NULL,1,NULL);
  44.     xTaskCreate(vTask3,"Task3",100,NULL,1,NULL);
  45.     xTaskCreate(vTask4,"Task4",100,NULL,1,NULL);
  46.     /* Create the queue. */
  47.     vTaskStartScheduler();
  48.     /* If all is well the next line of code will not be reached as the scheduler
  49.     will be    running. If the next line is reached then it is likely that there was
  50.     insufficient heap available for the idle task to be created. */
  51.     for( ;; );
  52. }

RX62Nの12bitAD変換を使うその2

2015-11-26 15:00:48 | RX62N
RX62Nの12bitAD変換器を動かすプログラムのサンプルです。MTU0のTGRAのコンペアマッチを使い一定間隔で変換を行います。AD変換結果の読み出しに割り込みを使用しています。

  1. #include <stdio.h>
  2. #include <machine.h>
  3. #include "iodefine.h"
  4. #include "vect.h"
  5. #define PCLK    48    //PCLK = 48MHz
  6. /*
  7.  * MTU0の初期化
  8.  * TGRAのコンペアマッチでAD変換をスタートさせる
  9.  *
  10.  * 12bit A/Dコンバータ初期化
  11.  * AN0のみ使用
  12.  */
  13. void initMTU0_S12AD(void)
  14. {
  15.     MSTP(MTU0) = 0;                    //タイマMTU0回路動作
  16.     MTU0.TCR.BIT.CCLR = 1;            //TGRAコンペアマッチでカウンタクリア
  17.     MTU0.TCR.BIT.CKEG = 0;            //クロックエッジ選択ビット (使用しない)
  18.     MTU0.TCR.BIT.TPSC = 3;            //PCLK/64でカウント
  19.     MTU0.TMDR.BIT.MD = 0;            //通常動作
  20.     MTU0.TIER.BIT.TTGE = 1;            //A/D変換開始要求の発生を許可
  21.     MTU0.TCNT = 0;
  22.     MTU0.TGRA = PCLK*1000000L/64L/1000L - 1L;    // PCLK = 48MHzで1秒間に1000回AD変換を行う
  23.     MSTP(S12AD) = 0;                // 12bit AD変換回路動作
  24.     delay_ms(100);                    // AD変換回路が安定するのを待つ
  25.     PORT4.DDR.BIT.B0 = 0;            // AN0を使用するためデジタル入力に
  26.     S12AD.ADCSR.BIT.CKS = 3;        // クロック PCLK/1
  27.     S12AD.ADCSR.BIT.EXTRG = 0;        // A/D開始トリガ選択レジスタ(ADSTRGR)で選択されたタイマ要因による、スキャン変換の開始を選択
  28.     S12AD.ADCSR.BIT.TRGE = 1;        // 外部トリガ(ADTRG0#)または、MTU、TMRトリガによるスキャン変換を許可
  29.     S12AD.ADCSR.BIT.ADIE = 1;        // スキャン終了後のS12ADI0割り込み発生の許可
  30.     IR(S12AD,ADI) = 0;                // 割り込みフラグクリア
  31.     IEN(S12AD,ADI) = 1;                // 割込み許可
  32.     IPR(S12AD,ADI) = 0x01;            // 割り込み優先順位設定
  33.     S12AD.ADANS.BIT.ANS = 0x01;        // AN0のみ変換
  34.     S12AD.ADCER.BIT.ADRFMT = 0;        // 保存データは右詰め
  35.     S12AD.ADSTRGR.BIT.ADSTRS = 1;    // TRG0AN_0トリガで変換開始
  36.     MTUA.TSTR.BIT.CST0 = 1;            // タイマMTU0スタート
  37. }
  38. /*
  39.  * S12AD ADI
  40.  * AD変換終了で呼び出される割り込み関数
  41.  * AD変換の結果を表示
  42.  */
  43. //
  44. void Excep_S12AD_ADI(void)
  45. {
  46.     int ans;
  47.     ans = S12AD.ADDR0;
  48.     printf("AD value %d\n",ans);
  49. }
  50. int main(void)
  51. {
  52.     volatile int i;
  53.     Initialization();
  54.     initMTU0_S12AD();                        //AD変換初期化
  55.     printf("A/D converter test.\n");
  56.     while (1) {
  57.         //何もしない 割込みで動作
  58.     }
  59. }

RX62Nの12bitAD変換を使うその1

2015-11-26 14:51:43 | RX62N
RX62Nの12bitAD変換器を動かすプログラムのサンプルです。

  1. #include <stdio.h>
  2. #include <machine.h>
  3. #include "iodefine.h"
  4. /*
  5.  * 12bit A/Dコンバータ初期化
  6.  * AN0のみ使用
  7.  */
  8. void s12ad_init(void) {
  9.     MSTP(S12AD) = 0;
  10.     delay_ms(100);                // AD変換回路が安定するのを待つ
  11.     PORT4.DDR.BIT.B0 = 0;        // AN0を使用するためデジタル入力に
  12.     S12AD.ADCSR.BIT.CKS = 0x03;    // クロック PCLK/1
  13.     S12AD.ADANS.BIT.ANS = 0x01;    // AN0のみ変換
  14.     S12AD.ADCER.BIT.ADRFMT = 0;    // 保存データは右詰め
  15. }
  16. /*
  17.  * AD変換を実行
  18.  */
  19. unsigned short get_s12ad(void) {
  20.   int i;
  21.   unsigned short adv;
  22.   S12AD.ADCSR.BIT.ADST = 1;         // AD変換開始
  23.   while(S12AD.ADCSR.BIT.ADST==1);    // AD変換が終了するのを待つ
  24.   adv = S12AD.ADDR0;                // 結果の読み出し
  25.   return adv;
  26. }
  27. int main(void)
  28. {
  29.     int adv;
  30.     Initialization();
  31.     s12ad_init();                        //AD変換初期化
  32.     printf("A/D converter test.\n");
  33.     while (1) {
  34.         adv = get_s12ad();
  35.         printf("AD value %d\n",adv);
  36.         delay_ms(100);
  37.     }
  38. }