2013年4月25日木曜日

PIC12F1822(jalv2)でNikon ML-L3互換リモコン


Nikonのデジカメ用リモコンML-L3の互換機をPIC12F1822で作ります。
ML-L3に解析データは先人の知恵を参考にさせて頂いてます。



PIC12F1822は今回初めて使う石ですが、JalV2でサポートされているので安心。

完成品

完成品

コードの説明

delay

m秒単位の_usec_delay(2_000)だと時間が安定してなくて、delayライブラリのdelay_1ms(2)を使いました。

定数判定の最適化

JalV2は定数の分岐は最適化されてコンパイル時にコード生成するのでクロック指定の部分でも
case target_clock of 32_000_000: block pragma
pragma target PLLEN P4 OSCCON_SPLLEN = 1
OSCCON_IRCF = 0b1110 -- 32MHz = 8Mhz * 4
OSCCON_SCS = 0
end block
16_000_000: OSCCON_IRCF = 0b1111 -- 16MHz
8_000_000: OSCCON_IRCF = 0b1110 -- 8MHz
4_000_000: OSCCON_IRCF = 0b1101 -- 4MHz
2_000_000: OSCCON_IRCF = 0b1100 -- 2MHz
1_000_000: OSCCON_IRCF = 0b1011 -- 1MHz
500_000: OSCCON_IRCF = 0b1010 -- 500kHz HF
250_000: OSCCON_IRCF = 0b1001 -- 250kHz HF
125_000: OSCCON_IRCF = 0b1000 -- 125kHz HF
otherwise OSCCON_IRCF = 0b1101 -- 4MHz
end case
実際には

;   56   16_000_000: OSCCON_IRCF = 0b1111              -- 16MHz
                               movlw    135
                               andwf    v_osccon,w
                               iorlw    120
                               movwf    v_osccon

の部分だけコードになってます。
c言語だとプリプロセッサ命令(#IF)使う部分をJalV2は普通に記述できるんです。
凄いですね。


部品

PIC12F1822 80円/1個
2N7002k 200円/40個
赤外線LED 100円/10個
CR2032 100円/2個
CR2032電池ホルダー 35円/1個
Frisk基板 100円/2枚
Frisk空き箱
抵抗20Ω 100円/100本

SMD部品を先にはんだ付け
 
 


コード

-- ------------------------------------------------------
-- Title: Nikon ML-L3 IR Wireless Remote Control of the Microchip pic12f1822
--
-- Author: Masahiko KANETAKA, Copyright (c) 2013, all rights reserved.
-- http://kane4d.blogspot.jp/
-- kane4d at gmail.com
--
-- Adapted-by:
--
-- Compiler: 2.4p
--
-- Description:
-- Nikon ML-L3 IR Wireless Remote Control for Microchip PIC12f1822.
--
-- Sources:
--
-- Notes:
--  - File creation date/time: 13 Apr 2013 14:11:50.
--
-- ------------------------------------------------------
--
include 12f1822                    -- target PICmicro
--      Vdd 1--+---+--8 Vss
-- CCP1/RA5 2--|   |--7 RA0/ICSPDAT
-- CLKo/RA4 3--|   |--6 RA1/ICSPCLK
-- MCLR/RA3 4--+---+--5 RA2/CCP1
--
-- #1 Vdd
-- #3 CLOCK Out
-- #5 PWM LED Drive
-- #8 Vss

-- include 16f1823
--      Vdd 1--+---+--14 Vss
--      RA5 2--|   |--13 RA0/ICSPDAT
--      RA4 3--|   |--12 RA1/ICSPCLK
-- MCLR/RA3 4--|   |--11 RA2
--      RC5 5--|   |--10 RC0
--      RC4 6--|   |--9  RC1
--      RC3 7--+---+--8  RC2


-- This program assumes that a 4 MHz Internal OSC
pragma target clock 16_000_000     -- oscillator frequency
pragma target PLLEN P1
pragma target OSC      INTOSC_NOCLKOUT     -- INTOSC
OSCCON_SPLLEN = 0
OSCCON_SCS = 0b10
case target_clock of
  32_000_000: block
              pragma target PLLEN P4
              OSCCON_SPLLEN = 1
              OSCCON_IRCF = 0b1110              -- 32MHz = 8Mhz * 4
              OSCCON_SCS = 0
              end block
  16_000_000: OSCCON_IRCF = 0b1111              -- 16MHz
  8_000_000:  OSCCON_IRCF = 0b1110              -- 8MHz
  4_000_000:  OSCCON_IRCF = 0b1101              -- 4MHz
  2_000_000:  OSCCON_IRCF = 0b1100              -- 2MHz
  1_000_000:  OSCCON_IRCF = 0b1011              -- 1MHz
  500_000:    OSCCON_IRCF = 0b1010              -- 500kHz HF
  250_000:    OSCCON_IRCF = 0b1001              -- 250kHz HF
  125_000:    OSCCON_IRCF = 0b1000              -- 125kHz HF
  otherwise   OSCCON_IRCF = 0b1101              -- 4MHz
end case

-- configuration memory settings (fuses)
pragma target WDT      disabled     -- no watchdog
pragma target DEBUG    disabled     -- no debugging
pragma target LVP      disabled     -- no Low Voltage Programming
pragma target MCLR     internal     -- reset internally
pragma target CLKOUTEN disabled     --enabled

include pwm_hardware
include delay

enable_digital_io()                -- make all pins digital I/O
--

alias clkout_test_pin is pin_CLKOUT --RA4
pin_CLKOUT_direction = output

if (true) then
   pin_CCP1_RA2_direction = output
   APFCON_CCP1SEL = 0 --RA2
else
   pin_CCP1_RA5_direction = output
   APFCON_CCP1SEL = 1 --RA5
end if

-- pwm_max_resolution(1)
pwm_set_frequency(38_400)     -- 38.4KHz
pwm1_set_dutycycle_percent(0)

-- http://www002.upp.so-net.ne.jp/hard-and-soft/IR_Remocon/IR_Remocon.html
-- http://www.sbprojects.com/projects/nikon/index.php
--     high      low     high      low     high    low     high
--  +--------+         +-------+        +-------+        +-------+
--  |        | 28000us |       | 1580us |       | 3580us |       | 63000us
----+ 2000us +---------+ 400us +--------+ 400us +--------+ 400us +---------+

_usec_delay(2_000)
pwm1_set_dutycycle_percent(50)
for 2 loop
--forever loop
   pwm1_on()
   --_usec_delay(2_000)
   delay_1ms(2)
   pwm1_off()
   --_usec_delay(28_000)
   delay_1ms(28)
   pwm1_on()
   --_usec_delay(400)
   delay_10us(40)
   pwm1_off()
   --_usec_delay(1_580)
   delay_10us(158)
   pwm1_on()
   --_usec_delay(400)
   delay_10us(40)
   pwm1_off()
   --_usec_delay(3_580)
   delay_1ms(3)
   delay_10us(58)
   pwm1_on()
   --_usec_delay(400)
   delay_10us(40)
   pwm1_off()
   --_usec_delay(63_000)
   delay_1ms(63)
end loop

pwm1_off()
asm sleep
--

JalV2のソースとHEX

 

OSC16MHzはPWM38.4Hzを発生できるクロックなら変更可能だと思う。
 
2013/5/5 OSC1MHzに変更 1MHzだとdelay関数が正しく働かないので、実測値でパラメータを設定しました。

 

 

 




2013年4月16日火曜日

atmega328pコンポーネントテスター3号機

調子に乗って3号機を作成。
arduinoのシールドとして動作し、LCDやボタンを省きシリアル出力に特化したバージョンです。

arduinoを持っていれば200円くらいの部品代で作れます。

ケース加工中
基板をけちってジャンパーで渡しました。

表から
カーボン抵抗5%なので、将来変更できるようにセパレート構造になってます。
裏から
プルアップ抵抗は10kΩ~30kΩなら何でもOK

リセットの回路図
次はPC側の読み込みソフト編


2013年4月11日木曜日

atmega328pコンポーネントテスター2号機

1号機を作る最終段階で発見したのが、シリアル出力機能。
PC3からソフトシリアル9600bpsで液晶画面と同じものが出力されます。

1号機は金属皮膜抵抗1%を使いましたが、今回はカーボン抵抗5%を使います。
お小遣いを握りしめ先週末に秋月に金属皮膜抵抗1% 680Ωと470kΩを買いに行きましたが、なんと470kΩは取り扱いが無いのです。行き場を失ったお小遣いは「お楽しみ袋」に化けてしまいました。
夢の0.1%の抵抗はお父さんのお小遣いでは高くて使えません。

秋月のarduino互換機AE-Atmegaの拡張基板として、両面C基板を使いました。
部品配置
arduinoのジャンパーを引き出して利用しました。

  • RxをPC3へ
  • RSTをPD7へ(DTR on/offでテストボタンを動作させるという目論見)

電源回路はarduino側にすべてあるので、C基板の半分しか使ってません。
一応、LCDを付けて動作テストもしてみました。
LCDの動作テスト

今回はバックライトを380kΩで駆動。
ファームを書き込みの際にFUSE設定するのを忘れ、スロー動作で値も変な状態になってしまいました。いきなりシリアルでテストしていたら、動作速度がおかしいことに気付かなかったでしょう。
atmega328pのFUSEはF7/D9/FCです。

atmega328p 16MHzの設定でコンパイルしたHEXはこちら


arduinoはピン番号が揃ってるから接続も簡単でした。
teratermで試したところ、受信動作はOK
PC側からの測定開始にはteratermのマクロでsetdtrコマンドを使いました。
でも、残念なことにDTR on/offで測定する目論見は失敗でした。
PD7がLOWになっている時間が短いのが問題かも...

次号機はAE-Atmega上で直接構築してみます。

2013/4/11 23:00
この回路図の更新したものがあるのですが、画像サーバとの連携エラーで画像を変更できない状態です。

2013/4/12 8:00
RST<->PD7間にS-8053HNBを入れたらsetdtrで計測開始出来ました。なぜかエラーで画像更新できない。




S-8053HNB
以前、千石通商のジャンクパーツ袋に入っていたSIIのボルテージディテクタS-8053HNB
3VでOpenDrainに落ちる。

DTR->0.1μ 水色、PD7 黄色
Pin1 Out(Drain) PD7
Pin2 Vdd DTR->0.1μF
Pin3 Vss GND
に接続




80ms間PD7がLOWになって、めでたく自動測定開始されました。
このチップの検出限界になると、Outが閉じる性質を利用してます。


  1. コンデンサに充電
  2. コンデンサが放電
  3. 3V以下になるとPD7 LOW
  4. さらにコンデンサが放電
  5. まだ、PD7 LOWのまま
  6. 検出限界まで来るとOutが閉じてPD7 HIGHになる


atmega328pでコンポーネントテスター


aitendoのatmega8基板
もちろんatmega328pでも使える

1年くらい前にavrで作成されたトランジスタテスターが紹介されていた。
その頃は、ドイツ語のサイトで???で、回路図もソースも読まずに時が流れて...

ジャンクパーツの手助けになれば ということでLCメータを作ったりしましたが、秋月の「お楽しみ袋」のパーツの量が尋常ではなく、ここで重たい腰を上げねばと一念発起。
avr transistor testerについて調べてみると超シンプルな設計思想に驚き、日本語でも情報発信されているnobuさんのページを参考に1号機を作成。

以前作ったaitendoのマイコンPCB[PCB-ATMEGA8]+atmega328p(16MHz)をベースとして作成しました。
基本の回路図では8MHz駆動になっていたのですが、ソースを読むと16MHzも考量されているようだったので見切り発車状態でいざはんだ付け。

部品配置
緑C基板の下にatmega328pの基板がいます。
作ってから気付いたのは基板の半分が1.5V→5Vの昇圧回路になってます。なんでも作ってみないと分からないことがあります。
今、新規に作るのであれば006P 9Vにスーパー3端子レギュレータ 5V500mA R-78E5.0-0.5を使います。
ケース加工が苦手です
Makefileの

PARTNO = m168
→PARTNO = m328p

OP_MHZ = 8
→OP_MHZ = 16
2か所変更だけで動作しました。


カッコ悪いけど、3個100円のタッパに入れて1号機完成。
端子の順番が2-1-3となってカッコ悪です。
PEAKの半導体アナライザみたいにテストクリップの色で表現しようかなぁ。

調子に乗って2号機も作ってます。

変換基板で3.3Vレギュレータ

デジカメを新調した記念にブログ更新。
以前、秋月のSOT23変換基板を使った小物なんてものを作りましたが、その続編。
ジャンクで手に入れたBH33MA3WHFV-TR 低損失ポイントレギュレーター 3.3V300mAがたくさんあるので、これを使って小物電子工作。

6ピン0.5mmピッチの極小です。
これを秋月の0.5mmピッチIC変換基板(5枚入)にのせてみました。最近の秋月の変換基板には裏にもチップを載せることができるので、これを最大限に生かした配置にしました。
変換基板にはサーマルビアが無いので、放熱は???です。
2年前の死蔵ペースト半田をコテライザーミニのホットブローで炙って出来上がり。
変換基板が8ピンなのでGNDをジャンパー大移動して4ピンSIPに仕上がりました。

久しぶりに更新

デジカメが手元にないと更新が億劫になってしまい、何も更新もせず日々が過ぎて行きました。
先月、型落ちのデジカメ(CASIO EX-ZR300)を新調するも、3日目でレンズエラーで販売店へ。
同じ機種交換を所望したが、在庫なしで返品になってしまった。
あーー腰砕けの日々...

2011年7月18日月曜日

aitendoのSTM32F103R基板を作ってみました(MapleIDE移植編)

irukaさんのページを参考にしてaitendoのSTM32F103R基板でもMapleIDEが動くようにしてみました。

pinModeがarduinoから拡張されてるのが新鮮です。
この基板のタクトスイッチはGNDに直接つながってるだけなので、INPUT_PULLUPを使いました。

Uploaderとしてavrdudeを使うにはauto_resetの設定に関係なくCOMxxにアクセスできないとavrdude.exeに処理が移らないようです。

後でファイルをアップしますが、今日は眠いので修正点の一覧だけで...

boards.txtに追加
##############################################################
Aitendo103R.name=Aitendo STM32F103R Mini to Flash
Aitendo103R.upload.file_type=bin
Aitendo103R.upload.maximum_size=108000
Aitendo103R.upload.ram.maximum_size=17000
Aitendo103R.upload.flash.maximum_size=108000
#Aitendo103R.upload.usbID=0483:DF11
Aitendo103R.upload.usbID=1EAF:0003
Aitendo103R.upload.altID=2
Aitendo103R.upload.uploader=avrdude
#Aitendo103R.upload.auto_reset=true
Aitendo103R.upload.protocol=ARMBOOT_STBEE
Aitendo103R.upload.speed=115200
#Aitendo103R.build.board=maple
Aitendo103R.build.board=Aitendo103R
Aitendo103R.build.mcu=STM32F103RB
Aitendo103R.build.family=cortex-m3
Aitendo103R.build.f_cpu=72000000L
Aitendo103R.build.core=maple
Aitendo103R.build.vect=VECT_TAB_FLASH
Aitendo103R.build.linker=maple/flashAitendo103R.ld
#Aitendo103R.build.linker=maple/flash.ld
Aitendo103R.build.using=armcompiler
Aitendo103R.build.density=STM32_MEDIUM_DENSITY
Aitendo103R.build.error_led_port=GPIOB
Aitendo103R.build.error_led_pin=8

libmaple.hは開始アドレスを指定

#ifdef BOARD_Aitendo103R
#define USER_ADDR_ROM 0x08002000
#else
#define USER_ADDR_ROM 0x08005000
#endif

boards.hはピンなサインを追加
#elif defined(BOARD_STM32VLD)
#include "maple_STM32VLD.h"
#elif defined(BOARD_Aitendo103R)
#include "maple_Aitendo103R.h"
#else

usb_config.h

#elif defined(BOARD_STM32VLD)
    #define VCOM_ID_PRODUCT      0x0004
    #define USB_DISC_DEV         GPIOB
    #define USB_DISC_PIN         9

#elif defined(BOARD_Aitendo103R)
    #define VCOM_ID_PRODUCT      0x0004
    #define USB_DISC_DEV         GPIOC
    #define USB_DISC_PIN         12
#else

maple_Aitendo103R.hを追加
PAxx, PBxx等のピン名でもアクセスできるようにしてみました。
/******************************************************************************
 * The MIT License
 *
 * Copyright (c) 2011 LeafLabs, LLC.
 *
 * 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.
 *****************************************************************************/
/**
 * @file   maple_mini.h
 * @author Marti Bolivar <mbolivar@leaflabs.com>
 * @brief  Private include file for Maple Mini in boards.h
 *
 * See maple.h for more information on these definitions.
 */
#include "gpio.h"
#include "timer.h"
#include "wirish_types.h"
#ifndef _BOARD_MAPLE_MINI_H_
#define _BOARD_MAPLE_MINI_H_
#define CYCLES_PER_MICROSECOND    72
#define SYSTICK_RELOAD_VAL     71999 /* takes a cycle to reload */
#define BOARD_BUTTON_PIN          35
#define BOARD_LED_PIN             34
#define BOARD_NR_USARTS           3
#define BOARD_USART1_TX_PIN       26
#define BOARD_USART1_RX_PIN       25
#define BOARD_USART2_TX_PIN       9
#define BOARD_USART2_RX_PIN       8
#define BOARD_USART3_TX_PIN       1
#define BOARD_USART3_RX_PIN       0
#define BOARD_NR_SPI              2
#define BOARD_SPI1_NSS_PIN        7
#define BOARD_SPI1_MOSI_PIN       4
#define BOARD_SPI1_MISO_PIN       5
#define BOARD_SPI1_SCK_PIN        6
#define BOARD_SPI2_NSS_PIN        31
#define BOARD_SPI2_MOSI_PIN       28
#define BOARD_SPI2_MISO_PIN       29
#define BOARD_SPI2_SCK_PIN        30
#define BOARD_NR_GPIO_PINS        51
#define BOARD_NR_PWM_PINS         12
#define BOARD_NR_ADC_PINS          16
#define BOARD_NR_USED_PINS         8
#define BOARD_JTMS_SWDIO_PIN      22
#define BOARD_JTCK_SWCLK_PIN      21
#define BOARD_JTDI_PIN            20
#define BOARD_JTDO_PIN            19
#define BOARD_NJTRST_PIN          18
enum {
 PA0 = 11, PA1 = 10, PA2 = 9, PA3 = 8, PA4 = 7, PA5 = 6, PA6 = 5, PA7 = 4,
 PA8 = 27, PA9 = 26, PA10 = 25, PA11 = 24, PA12 = 23, PA13 = 22, PA14 = 21, PA15 = 20,
 PB0 = 3, PB1 = 33, PB2 = 2, PB3 = 19, PB4 = 18, PB5 = 17, PB6 = 16, PB7 = 15,
 PB8 = 32, PB9 = 34, PB10 = 1, PB11 = 0, PB12 = 31, PB13 = 30, PB14 = 29, PB15 = 28,
 PC0 = 35, PC1 = 36, PC2 = 37, PC3 = 38, PC4 = 39, PC5 = 40, PC6 = 41, PC7 = 42,
 PC8 = 43, PC9 = 44, PC10 = 45, PC11 = 46, PC12 = 47, PC13 = 14, PC14 = 13, PC15 = 12,
 PD0 = 48, PD1 = 49, PD2 = 50,
};
#endif
maple_Aitendo103R.cpp
全ピンアクセスできるようにPIN_MAPを拡張
boardPWMPinsはこれから修正します。

/******************************************************************************
 * The MIT License
 *
 * Copyright (c) 2011 LeafLabs, LLC.
 *
 * 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.
 *****************************************************************************/
/**
 * @file   maple_mini.cpp
 * @author Marti Bolivar <mbolivar@leaflabs.com>
 * @brief  Maple Mini PIN_MAP and boardInit().
 */
#include "maple_Aitendo103R.h"
#include "gpio.h"
#include "wirish_debug.h"
#ifdef BOARD_Aitendo103R
/* Since we want the Serial Wire/JTAG pins as GPIOs, disable both SW
 * and JTAG debug support */
void boardInit(void) {
    disableDebugPorts();
}
extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS] = {
    /* Top header */
 // .*?/\*\s+D(\d+)/(P[A-G]\d+).*?\*/
 // \2 = \1,
    {GPIOB,   NULL, NULL, 11, 0, ADCx}, /* D0/PB11 */
    {GPIOB,   NULL, NULL, 10, 0, ADCx}, /* D1/PB10 */
    {GPIOB,   NULL, NULL,  2, 0, ADCx}, /* D2/PB2 */
    {GPIOB, TIMER3, ADC1,  0, 3,    8}, /* D3/PB0 */
    {GPIOA, TIMER3, ADC1,  7, 2,    7}, /* D4/PA7 */
    {GPIOA, TIMER3, ADC1,  6, 1,    6}, /* D5/PA6 */
    {GPIOA,   NULL, ADC1,  5, 0,    5}, /* D6/PA5 */
    {GPIOA,   NULL, ADC1,  4, 0,    4}, /* D7/PA4 */
    {GPIOA, TIMER2, ADC1,  3, 4,    3}, /* D8/PA3 */
    {GPIOA, TIMER2, ADC1,  2, 3,    2}, /* D9/PA2 */
    {GPIOA, TIMER2, ADC1,  1, 2,    1}, /* D10/PA1 */
    {GPIOA, TIMER2, ADC1,  0, 1,    0}, /* D11/PA0 */
    {GPIOC,   NULL, NULL, 15, 0, ADCx}, /* D12/PC15(OSC32_OUT) */
    {GPIOC,   NULL, NULL, 14, 0, ADCx}, /* D13/PC14(OSC32_IN) */
    {GPIOC,   NULL, NULL, 13, 0, ADCx}, /* D14/PC13 */
    /* Bottom header */
    {GPIOB, TIMER4, NULL,  7, 2, ADCx}, /* D15/PB7 */
    {GPIOB, TIMER4, NULL,  6, 1, ADCx}, /* D16/PB6 */
    {GPIOB,   NULL, NULL,  5, 0, ADCx}, /* D17/PB5 */
    {GPIOB,   NULL, NULL,  4, 0, ADCx}, /* D18/PB4 */
    {GPIOB,   NULL, NULL,  3, 0, ADCx}, /* D19/PB3 */
    {GPIOA,   NULL, NULL, 15, 0, ADCx}, /* D20/PA15 */
    {GPIOA,   NULL, NULL, 14, 0, ADCx}, /* D21/PA14 */
    {GPIOA,   NULL, NULL, 13, 0, ADCx}, /* D22/PA13 */
    {GPIOA,   NULL, NULL, 12, 0, ADCx}, /* D23/PA12(USB_DP) */
    {GPIOA, TIMER1, NULL, 11, 4, ADCx}, /* D24/PA11(USB DM) */
    {GPIOA, TIMER1, NULL, 10, 3, ADCx}, /* D25/PA10 */
    {GPIOA, TIMER1, NULL,  9, 2, ADCx}, /* D26/PA9 */
    {GPIOA, TIMER1, NULL,  8, 1, ADCx}, /* D27/PA8 */
    {GPIOB,   NULL, NULL, 15, 0, ADCx}, /* D28/PB15 */
    {GPIOB,   NULL, NULL, 14, 0, ADCx}, /* D29/PB14 */
    {GPIOB,   NULL, NULL, 13, 0, ADCx}, /* D30/PB13 */
    {GPIOB,   NULL, NULL, 12, 0, ADCx}, /* D31/PB12 */
    {GPIOB, TIMER4, NULL,  8, 3, ADCx}, /* D32/PB8(LED2) */
    {GPIOB, TIMER3, ADC1,  1, 4,    9}, /* D33/PB1 */
    {GPIOB, TIMER4, NULL,  9, 4, ADCx}, /* D34/PB9(LED1) */
   
    {GPIOC,   NULL, ADC1,  0, 0,   10}, /* D35/PC0(S2) */
    {GPIOC,   NULL, ADC1,  1, 0,   11}, /* D36/PC1(S3) */
    {GPIOC,   NULL, ADC1,  2, 0,   12}, /* D37/PC2 */
    {GPIOC,   NULL, ADC1,  3, 0,   13}, /* D38/PC3 */
    {GPIOC,   NULL, ADC1,  4, 0,   14}, /* D39/PC4 */
    {GPIOC,   NULL, ADC1,  5, 0,   15}, /* D40/PC5 */
    {GPIOC,   NULL, NULL,  6, 0, ADCx}, /* D41/PC6 */
    {GPIOC,   NULL, NULL,  7, 0, ADCx}, /* D42/PC7 */
    {GPIOC,   NULL, NULL,  8, 0, ADCx}, /* D43/PC8 */
    {GPIOC,   NULL, NULL,  9, 0, ADCx}, /* D44/PC9 */
    {GPIOC,   NULL, NULL, 10, 0, ADCx}, /* D45/PC10 */
    {GPIOC,   NULL, NULL, 11, 0, ADCx}, /* D46/PC11 */
    {GPIOC,   NULL, NULL, 12, 0, ADCx}, /* D47/PC12 */
   
    {GPIOD,   NULL, NULL,  0, 0, ADCx}, /* D48/PD0(OSC_IN) */
    {GPIOD,   NULL, NULL,  1, 0, ADCx}, /* D49/PD1(OSC_OUT) */
    {GPIOD,   NULL, NULL,  2, 0, ADCx}, /* D50/PD2 */
};
extern const uint8 boardPWMPins[BOARD_NR_PWM_PINS] __FLASH__ = {
    3, 4, 5, 8, 9, 10, 11, 15, 16, 25, 26, 27
};
extern const uint8 boardADCPins[BOARD_NR_ADC_PINS] __FLASH__ = {
    3, 4, 5, 6, 7, 8, 9, 10, 11,
    33,
    35, 36, 37, 38, 39, 40,
};
#define USB_DP 23
#define USB_DM 24
extern const uint8 boardUsedPins[BOARD_NR_USED_PINS] __FLASH__ = {
    BOARD_LED_PIN, BOARD_BUTTON_PIN, USB_DP, USB_DM,
    48, 49, //OSC
    12, 13, //OSC32
};
#endif