Compare commits

...

88 Commits

Author SHA1 Message Date
NIIBE Yutaka
a921d408c5 version 0.18 2012-05-15 13:50:32 +09:00
NIIBE Yutaka
4505715cf3 fix 2012-05-14 16:10:26 +09:00
NIIBE Yutaka
a8b116b93f add key removal tool 2012-05-14 15:38:50 +09:00
NIIBE Yutaka
5ff82b6d8b fix 2012-05-14 15:38:03 +09:00
NIIBE Yutaka
ee61781b92 more cleanup 2012-05-14 14:26:44 +09:00
NIIBE Yutaka
9275a6fdcb cleanup 2012-05-14 14:25:09 +09:00
NIIBE Yutaka
a158ea48ab rename 2012-05-14 13:16:43 +09:00
NIIBE Yutaka
27f26564ba fix description 2012-05-14 11:57:34 +09:00
NIIBE Yutaka
2f38503c61 remove void statements 2012-05-14 11:56:56 +09:00
NIIBE Yutaka
7fb547a87e cleanup usage of USB endpoint 2012-05-12 08:06:33 +09:00
NIIBE Yutaka
f5cefbcab4 fix typo 2012-05-11 14:14:11 +09:00
NIIBE Yutaka
ac28ee171c configure option --vidpid to specify USB device ID 2012-05-11 14:09:54 +09:00
NIIBE Yutaka
a0a1b8177b Fixes for New USB stack 2012-05-11 09:28:04 +09:00
NIIBE Yutaka
ab8a3eed29 configure: mention FST_01 2012-05-11 09:23:57 +09:00
NIIBE Yutaka
b56c3b81ec New USB stack 2012-05-10 19:01:01 +09:00
NIIBE Yutaka
c98f1fe8c6 fix usb config 2012-02-02 14:17:51 +09:00
NIIBE Yutaka
14673b825b version 0.17 2012-02-02 14:09:38 +09:00
NIIBE Yutaka
6550dd5353 space removal 2012-02-02 13:15:23 +09:00
NIIBE Yutaka
3d732a7c2d command chaining change 2012-02-02 12:18:47 +09:00
NIIBE Yutaka
aff9080b35 add alignment for gnuk.ld.in, add ChangeLog entries. 2012-01-21 00:33:17 +09:00
NIIBE Yutaka
21debc0567 no ext lc and le but short APDU only 2012-01-20 18:18:23 +09:00
NIIBE Yutaka
f92ee76db5 fixes two bugs 2012-01-19 14:23:01 +09:00
NIIBE Yutaka
87e4fd50c1 New API between gpg and ccid layer 2012-01-18 18:59:16 +09:00
NIIBE Yutaka
cbb2c6aab5 clean up USB API 2 2012-01-16 13:24:31 +09:00
NIIBE Yutaka
00541d7627 clean up USB API 2012-01-16 12:17:45 +09:00
NIIBE Yutaka
27277e56ee update pinpadtest.py 2012-01-12 10:39:16 +09:00
NIIBE Yutaka
4ee4417fb5 fix adding semicolon 2012-01-10 16:47:48 +09:00
NIIBE Yutaka
11351c8cae pinmodify is OK for unblock and put resetcode 2012-01-10 16:02:53 +09:00
NIIBE Yutaka
6abac73354 add an entry for NEWS 2012-01-05 17:04:00 +09:00
NIIBE Yutaka
41537cc827 check DF name on SELECT command 2012-01-05 15:14:35 +09:00
NIIBE Yutaka
a4e0e67340 pinpadtest.py: name change 2012-01-05 10:15:00 +09:00
NIIBE Yutaka
58f8470446 pinpad-test.py: comment change 2012-01-05 10:13:42 +09:00
NIIBE Yutaka
885e1c4ecb pinpad-test.py: add comment 2012-01-05 10:12:24 +09:00
NIIBE Yutaka
2c111d0b20 add result for pinpad-test 2012-01-04 17:33:34 +09:00
NIIBE Yutaka
35a62354ae pinpad-test.py: add --pinmin, --unblock2, and --put2 2012-01-04 11:57:19 +09:00
NIIBE Yutaka
18f3e72c32 fix pinpad-test.py for --add 2012-01-04 09:32:41 +09:00
NIIBE Yutaka
121df70044 fix long standing bug of RxCount setting for buffer bound (was bug in STmicro's software) 2011-12-28 22:16:14 +09:00
NIIBE Yutaka
48d89973c6 fixed long standing bug of ZLP 2011-12-28 12:27:16 +09:00
NIIBE Yutaka
60c1fe47ce fix pinpad-test.py 2011-12-27 14:10:39 +09:00
NIIBE Yutaka
c53afe1f96 fix pinpad-test.py 2011-12-27 10:34:24 +09:00
NIIBE Yutaka
3074058ff7 more fix to CERTDO_SUPPORT 2011-12-22 17:10:41 +09:00
NIIBE Yutaka
a0c8cf2ff4 Data Object 0x7f21 is now optional 2011-12-21 14:14:28 +09:00
NIIBE Yutaka
c0ab2ae830 DnDpinentry: cancellation 2011-12-20 10:39:47 +09:00
NIIBE Yutaka
a08669dfcd add messages to pinpad-test.py 2011-12-19 12:28:01 +09:00
NIIBE Yutaka
4a75aa47df improve pinpad-test.py 2011-12-19 12:17:22 +09:00
NIIBE Yutaka
1145fe0ad8 add new tool pinpad-test.py 2011-12-16 16:42:09 +09:00
NIIBE Yutaka
e2a4be1444 version 0.16 2011-12-14 12:51:26 +09:00
NIIBE Yutaka
b4d36a429f Fixes for PINPAD_SUPPORT 2011-12-14 12:45:20 +09:00
NIIBE Yutaka
a955cbec2f doc changes 2011-12-13 14:25:07 +09:00
NIIBE Yutaka
828b8f5768 merge dnd-support branch
fix vcom, change volume label
2011-12-13 13:29:23 +09:00
NIIBE Yutaka
d9be456fed fix 2011-12-13 11:26:12 +09:00
NIIBE Yutaka
5a9194d136 working now 2011-12-13 11:26:12 +09:00
NIIBE Yutaka
f58233aa5d more 2011-12-13 11:26:12 +09:00
NIIBE Yutaka
ec409fe8a4 rename 2011-12-13 11:26:12 +09:00
NIIBE Yutaka
231c50d9b5 cleanup 2011-12-13 11:26:11 +09:00
NIIBE Yutaka
696de23b52 usb mass storage class 2011-12-13 11:26:11 +09:00
NIIBE Yutaka
b113e6fa7b verify_other should not fail with no keys, but really checks PW1 2011-12-13 11:21:45 +09:00
NIIBE Yutaka
9dcb59f6aa minor cleanup 2011-12-08 10:56:48 +09:00
NIIBE Yutaka
351ce68729 better USB interoperability 2011-12-07 10:16:02 +09:00
NIIBE Yutaka
142dbabfd8 pinpad entry parameter handling 2011-12-07 09:38:48 +09:00
NIIBE Yutaka
1e94b262af pinpad support change 2011-12-01 18:23:10 +09:00
NIIBE Yutaka
268c41634a pinpad input for reset code 2011-11-29 15:18:25 +09:00
NIIBE Yutaka
bc71c39ea4 version 0.15 2011-11-24 15:40:38 +09:00
NIIBE Yutaka
0232c0a595 dfuse.py: fix handling of unaligned page 2011-11-24 13:54:12 +09:00
NIIBE Yutaka
62520ed0f4 tool/dfuse.py: support unaligned write and hole 2011-11-22 16:17:37 +09:00
NIIBE Yutaka
2c91633f59 add FST-01 description 2011-11-14 14:34:51 +09:00
NIIBE Yutaka
1ac7e20fb0 add FST_01 2011-11-14 14:22:37 +09:00
NIIBE Yutaka
e790bb783c change README and NEWS 2011-11-01 15:58:48 +09:00
NIIBE Yutaka
f45b7a5439 minor change for pin-cir.c 2011-11-01 15:13:58 +09:00
NIIBE Yutaka
6337371016 PIN input DIAL support change 2011-11-01 15:01:32 +09:00
NIIBE Yutaka
ed7e904aef PIN input CIR support change 2011-11-01 14:57:11 +09:00
NIIBE Yutaka
de39c484d0 support FST-01 8MHz 2011-11-01 11:41:20 +09:00
NIIBE Yutaka
ec7a2db43a cosmetic fix of src/ac.c 2011-11-01 11:39:47 +09:00
NIIBE Yutaka
f3a3808608 merge call-rsa.c change in the branch of rsa_1024_support. 2011-11-01 11:21:25 +09:00
NIIBE Yutaka
b2856d162e added more DEBUG_XX 2011-11-01 11:02:22 +09:00
NIIBE Yutaka
447139f74d fixed the bug for user who keeps using initial PW1 2011-11-01 11:01:16 +09:00
NIIBE Yutaka
683253b2eb workaround for GCC (summon-arm-toolchain) 2011-11-01 10:59:44 +09:00
NIIBE Yutaka
4749062338 increase (decreased) main (interrupt) stack size 2011-10-14 15:50:08 +09:00
NIIBE Yutaka
2181c1a428 version 0.14 2011-10-07 11:01:21 +09:00
NIIBE Yutaka
48f552b69b random_bits are not needed any more 2011-10-06 17:02:37 +09:00
NIIBE Yutaka
6aca64b664 cleanup 2011-10-06 16:58:20 +09:00
NIIBE Yutaka
3ec2df97b9 add missing neug.h 2011-10-06 16:57:28 +09:00
NIIBE Yutaka
94f2c25c3b NeuG integrated 2011-10-06 16:56:08 +09:00
NIIBE Yutaka
b1bb1354f8 Change for NeuG RNG 2011-10-06 11:23:49 +09:00
NIIBE Yutaka
1ef7813a53 add neug.c from NeuG/src/random.c 2011-10-06 11:22:51 +09:00
NIIBE Yutaka
9528867c2a minor boards fixes 2011-07-22 15:48:00 +09:00
NIIBE Yutaka
241f62238d add fix of Chibios 2011-07-04 15:57:05 +09:00
NIIBE Yutaka
dee75314fc adc macro rename patch (external) 2011-07-04 10:05:56 +09:00
108 changed files with 7517 additions and 12619 deletions

2
.gitignore vendored
View File

@@ -11,4 +11,4 @@ src/gnuk.dmp
src/gnuk.elf
src/gnuk.hex
src/gnuk.map
src/random_bits
src/*.inc

15
AUTHORS
View File

@@ -6,6 +6,14 @@ Kaz Kojima:
NIIBE Yutaka:
Founder of the project.
Added FST_01 support:
boards/FST_01/board.c
boards/FST_01/board.h
boards/FST_01/mcuconf.h
Added FST_01_00 support:
boards/FST_01_00/board.c
boards/FST_01_00/board.h
boards/FST_01_00/mcuconf.h
Added STBee support:
boards/STBEE/board.c
boards/STBEE/board.h
@@ -28,6 +36,9 @@ NIIBE Yutaka:
tool/intel_hex.py
Wrote a tool for Gnuk:
tool/gnuk_put_binary.py
tool/gnuk_put_binary_libusb.py
Wrote a tool for USB Hub:
tool/hub_ctrl.py
Wrote:
gnuk.svg
src/configure
@@ -49,5 +60,9 @@ NIIBE Yutaka:
src/random.c
src/pin-cir.c
src/pin-dial.c
src/pin-dnd.c
src/usb_msc.c
src/usb_msc.h
src/neug.c
*
and others.

627
ChangeLog
View File

@@ -1,3 +1,630 @@
2012-05-15 Niibe Yutaka <gniibe@fsij.org>
* Version 0.18.
* src/usb_desc.c (gnukStringSerial): Updated.
* src/main.c (EP3_IN_Callback, EP5_OUT_Callback): Move from
usb_endp.c.
* src/usb_endp.c: Remove.
2012-05-14 Niibe Yutaka <gniibe@fsij.org>
* tool/gnuk_remove_keys.py: New.
* src/openpgp-do.c (proc_key_import): Fix checking extended header.
* src/hardclock.c: Remove.
* src/usb_prop.c (MSC_INTERFACE_NO): New.
(gnuk_setup_endpoints_for_interface): Cleanup with MSC_INTERFACE_NO.
(gnuk_setup_with_data, gnuk_setup_with_nodata): Likewise.
* src/usb-msc.c: Rename from usb_msc.c.
* src/usb-msc.h: Rename from usb_msc.h.
* src/Makefile.in: Follow the rename of usb-msc.c and remove of
hardclock.c.
* src/pin-dnd.c, src/usb_prop.c: Follow the rename of usb-msc.h.
2012-05-12 Niibe Yutaka <gniibe@fsij.org>
* src/usb_msc.c (ep6_out): Rename (was: ep7_out).
(usb_start_receive): Use ep6_out and ENDP6.
(EP6_OUT_Callback): Rename (was: EP7_OUT_Callback).
Use ep6_out and ENDP6.
(msc_handle_command): Use ep6_out and ENDP6.
* src/main.c (main): Wait USB reset.
* src/usb-icc.c (EP1_OUT_Callback): Rename from EP2_OUT_Callback.
(USBthread): Use ENDP1 for both of epi_init and epo_init.
* src/usb_conf.h (ENDP1_RXADDR, ENDP2_TXADDR, ENDP6_RXADDR): New.
(ENDP3_TXADDR, ENDP4_TXADDR, ENDP5_RXADDR): New value.
(ENDP7_RXADDR): Remove.
* src/usb_desc.c (gnukConfigDescriptor): Use endpoint OUT1 (was
IN2), endpoint OUT6 (IN7).
* src/usb_prop.c (gnuk_setup_endpoints_for_interface): Use ENDP1
and ENDP6 for both directions.
2012-05-11 Niibe Yutaka <gniibe@fsij.org>
* src/configure (--vidpid): New mandatory option.
* GNUK_USB_DEVICE_ID: New file.
* src/usb_desc.c (gnukDeviceDescriptor): Include
usb-vid-pid-ver.c.inc.
(gnukStringVendor, gnukStringProduct): Remove. It's in the
file, usb-string-vender-product.c.inc.
* src/Makefile.in (distclean): Delete *.inc.
* src/usb_prop.c (vcom_port_setup_with_nodata) Rename.
(vcom_port_data_setup): Rename and fix return value.
* src/usb-cdc.h (VIRTUAL_COM_PORT_DATA_SIZE)
(VIRTUAL_COM_PORT_INT_SIZE): New.
* src/main.c (#include): Add usb-cdc.h.
* src/usb_desc.c (#include): Add usb-cdc.h.
* src/usb_endp.c (#include): Add usb_lld.h.
* src/configure ($help): Add FST_01.
2012-05-10 Niibe Yutaka <gniibe@fsij.org>
* STM32_USB-FS-Device_Driver, Virtual_COM_Port: Remove.
* src/usb_lld.c (#include): Don't include usb_lib.h.
(RECIPIENT, REG_BASE PMA_ADDR, CNTR, ISTR, FNR, DADDR, BTABLE)
(ISTR_CTR, ISTR_DOVR, ISTR_ERR, ISTR_WKUP, ISTR_SUSP, ISTR_RESET)
(ISTR_SOF, ISTR_ESOF, ISTR_DIR, ISTR_EP_ID, CLR_CTR, CLR_DOVR)
(CLR_ERR, CLR_WKUP, CLR_SUSP, CLR_RESET, CLR_SOF, CLR_ESOF)
(CNTR_CTRM, CNTR_DOVRM, CNTR_ERRM, CNTR_WKUPM, CNTR_SUSPM)
(CNTR_RESETM, CNTR_SOFM, CNTR_ESOFM, CNTR_RESUME, CNTR_FSUSP)
(CNTR_LPMODE, CNTR_PDWN, CNTR_FRES, DADDR_EF, DADDR_ADD)
(EP_CTR_RX, EP_DTOG_RX, EPRX_STAT, EP_SETUP, EP_T_FIELD, EP_KIND)
(EP_CTR_TX, EP_DTOG_TX, EPTX_STAT, EPADDR_FIELD, EPREG_MASK)
(EP_TX_DIS, EP_TX_STALL, EP_TX_NAK, EP_TX_VALID, EPTX_DTOG1)
(EPTX_DTOG2, EP_RX_DIS, EP_RX_STALL, EP_RX_NAK, EP_RX_VALID)
(EPRX_DTOG1, EPRX_DTOG2): New. Compatible to ST's USB-FS-Device_Lib.
(CH_IRQ_HANDLER): Call usb_interrupt_handler (was: USB_Istr).
(EP1_IN_Callback, EP2_IN_Callback, EP3_IN_Callback)
(EP4_IN_Callback, EP5_IN_Callback, EP6_IN_Callback)
(EP7_IN_Callback, EP1_OUT_Callback, EP2_OUT_Callback)
(EP3_OUT_Callback, EP4_OUT_Callback, EP5_OUT_Callback)
(EP6_OUT_Callback, EP7_OUT_Callback): New. Implement here.
Compatible to ST's USB-FS-Device_Lib.
(USB_MAX_PACKET_SIZE): New.
(GET_STATUS, CLEAR_FEATURE, RESERVED1, SET_FEATURE, RESERVED2)
(SET_ADDRESS, GET_DESCRIPTOR, SET_DESCRIPTOR, GET_CONFIGURATION)
(SET_CONFIGURATION, GET_INTERFACE, SET_INTERFACE)
(SYNCH_FRAME,TOTAL_REQUEST): New for USB control transfer.
(enum CONTROL_STATE): New for state machine of control pipe.
(enum FEATURE_SELECTOR): New.
(struct DATA_INFO, struct CONTROL_INFO, struct DEVICE_INFO): New.
(ctrl_p, dev_p, data_p, Control_Info, Device_Info, Data_Info):
New.
(usb_lld_stall_tx, usb_lld_stall_rx)
(usb_lld_tx_data_len, usb_lld_txcpy, usb_lld_tx_enable)
(usb_lld_write, usb_lld_rx_enable, usb_lld_rx_data_len)
(usb_lld_rxcpy): Move from usb_lld.h and not inline.
(usb_lld_reset, usb_lld_setup_endpoint)
(usb_lld_set_configuration, usb_lld_current_configuration)
(usb_lld_set_feature, usb_lld_set_data_to_send): New.
(usb_lld_to_pmabuf, usb_lld_from_pmabuf): Clean up.
(usb_lld_init): New implementation.
(st103_set_btable, st103_get_istr, st103_set_istr, st103_set_cntr)
(st103_set_daddr, st103_set_epreg, st103_get_epreg)
(st103_set_tx_addr, st103_get_tx_addr, st103_set_tx_count)
(st103_get_tx_count, st103_set_rx_addr, st103_get_rx_addr)
(st103_set_rx_buf_size, st103_get_rx_count, st103_ep_clear_ctr_rx)
(st103_ep_clear_ctr_tx, st103_ep_set_rxtx_status)
(st103_ep_set_rx_status, st103_ep_get_rx_status)
(st103_ep_set_tx_status, st103_ep_get_tx_status)
(st103_ep_clear_dtog_rx, st103_ep_clear_dtog_tx): New lower-level
functions for USB related registers access.
(usb_interrupt_handler, usb_handle_transfer)
(handle_datastage_out, handle_datastage_in, handle_setup0)
(handle_in0, handle_out0)
(std_none, std_get_status, std_clear_feature, std_set_feature,
std_set_address, std_get_descriptor, std_get_configuration,
std_set_configuration, std_get_interface, std_set_interface)
(std_request_handler): New USB stack implementation.
* src/usb_lld.h (usb_lld_stall_tx, usb_lld_stall_rx)
(usb_lld_tx_data_len, usb_lld_txcpy, usb_lld_tx_enable)
(usb_lld_write, usb_lld_rx_enable, usb_lld_rx_data_len)
(usb_lld_rxcpy): Those are not inline functions anymore.
(USB_DEVICE_DESCRIPTOR_TYPE, USB_CONFIGURATION_DESCRIPTOR_TYPE)
(USB_STRING_DESCRIPTOR_TYPE, USB_INTERFACE_DESCRIPTOR_TYPE)
(USB_ENDPOINT_DESCRIPTOR_TYPE, STANDARD_ENDPOINT_DESC_SIZE)
(ENDP0, ENDP1, ENDP2, ENDP3, ENDP4, ENDP5, ENDP6, ENDP7)
(EP_BULK, EP_CONTROL, EP_ISOCHRONOUS, EP_INTERRUPT)
(DEVICE_RECIPIENT, INTERFACE_RECIPIENT, ENDPOINT_RECIPIENT)
(ENDPOINT_RECIPIENT, OTHER_RECIPIENT)
(DEVICE_DESCRIPTOR, CONFIG_DESCRIPTOR, STRING_DESCRIPTOR)
(INTERFACE_DESCRIPTOR, ENDPOINT_DESCRIPTOR)
(REQUEST_TYPE, STANDARD_REQUEST, CLASS_REQUEST, VENDOR_REQUEST)
(USB_UNSUPPORT, USB_SUCCESS)
(USB_EVENT_RESET, USB_EVENT_ADDRESS, USB_EVENT_CONFIG)
(USB_EVENT_SUSPEND, USB_EVENT_WAKEUP, USB_EVENT_STALL)
(USB_SET_INTERFACE, USB_GET_INTERFACE, USB_QUERY_INTERFACE)
(UNCONNECTED, ATTACHED, POWERED, SUSPENDED, ADDRESSED)
(CONFIGURED, USB_Cable_Config): New. Compatible to ST's
USB-FS-Device_Lib.
(struct Descriptor, struct usb_device_method)
(Device_Descriptor, Config_Descriptor, String_Descriptors)
(STM32_USB_IRQ_PRIORITY, bDeviceState, Device_Method)
(usb_lld_init, usb_lld_reset, usb_lld_setup_endpoint)
(usb_lld_set_configuration, usb_lld_current_configuration)
(usb_lld_set_feature, usb_lld_set_data_to_send): New API.
* src/usb_prop.c(#include): Only include usb_lld.h for USB.
(SetEPRxCount_allocated_size): Remove.
(struct line_coding, line_coding, Virtual_Com_Port_Data_Setup)
(Virtual_Com_Port_NoData_Setup): Add from usb-cdc-vport.c.
(gnuk_device_init, gnuk_device_reset, gnuk_setup_with_data)
(gnuk_setup_with_nodata): Follow the API change of USB stack.
(gnuk_setup_endpoints_for_interface, gnuk_get_descriptor)
(gnuk_usb_event, gnuk_interface): New.
(gnuk_device_SetConfiguration, gnuk_device_SetInterface)
(gnuk_device_SetDeviceAddress, gnuk_device_Status_In)
(gnuk_device_Status_Out, gnuk_device_GetDeviceDescriptor)
(gnuk_device_GetConfigDescriptor, gnuk_device_GetStringDescriptor)
(gnuk_device_Get_Interface_Setting, gnuk_clock_frequencies)
(gnuk_data_rates, msc_lun_info, Device_Table)
(User_Standard_Requests): Remove.
(Device_Method): Replace Device_Property.
* src/usb_msc.c (#include): Only include usb_lld.h for USB.
* src/usb_endp.c (#include): Only include usb_lld.h for USB.
(EP5_OUT_Callback): Follow the API change of USB stack.
* src/usb_desc.c (#include): Only include usb_lld.h for USB.
Add usb_conf.h.
(Device_Descriptor, Config_Descriptor): Follow the API change
of USB stack.
(String_Descriptors): New, rename from String_Descriptor.
* src/usb_conf.h (EP_NUM, BTABLE_ADDRESS, IMR_MSK): Remove.
(NUM_STRING_DESC): Add.
* src/usb-icc.c (#include): Only include usb_lld.h for USB.
* src/usb-cdc-vport.c, src/usb_prop.h: Remove.
* src/stmusb.mk, src/vcomport.mk: Remove.
* src/main.c (#include): Only include usb_lld.h for USB.
(main): Remove call to USB_Init.
* src/Makefile.in (include): Remove stmusb.mk, vcomport.mk.
(VCOMSRC) [ENABLE_VCOMPORT]: Add.
(INCDIR): Remove STMUSBINCDIR and VCOMDIR.
* boards/common/hw_config.c (Enter_LowPowerMode)
(Leave_LowPowerMode): Remove.
2012-02-02 Niibe Yutaka <gniibe@fsij.org>
* Version 0.17.
* src/usb_desc.c (gnukStringSerial): Updated.
(gnukConfigDescriptor): Short APDU only.
* tool/gnuk_put_binary.py (cmd_get_response): New.
(cmd_select_openpgp, cmd_get_data): Call cmd_get_response.
2012-01-30 Niibe Yutaka <gniibe@fsij.org>
* src/usb-icc.c (struct ccid): Add chained_cls_ins_p1_p2.
(end_cmd_apdu_head, icc_cmd_apdu_data, icc_handle_data): Add checking
CMD APDU head for command chaining.
2012-01-20 Niibe Yutaka <gniibe@fsij.org>
Short APDU only CCID driver.
* STM32_USB-FS-Device_Driver/src/usb_core.c (DataStageOut)
(DataStageIn): Use usb_lld_to_pmabuf and usb_lld_from_pmabuf.
* src/configure (CERTDO_SUPPORT): Comment fix.
* src/gnuk.h (struct adpu): expected_res_size has type uint16_t.
(MAX_CMD_APDU_DATA_SIZE, MAX_RES_APDU_DATA_SIZE): New.
(MAX_CMD_APDU_SIZE, MAX_RES_APDU_SIZE, USB_BUF_SIZE): Remove.
(icc_state_p): New.
(set_res_sw): Rename from set_res_apdu.
* src/call-rsa.c (rsa_decrypt): Use MAX_RES_APDU_DATA_SIZE.
* src/openpgp.c (set_res_sw): Rename from set_res_apdu.
* src/openpgp.h: Use set_res_sw.
* src/main.c: Handle icc_state_p.
* src/openpgp-do.c (historical_bytes): command chaining but short
APDU only.
(extended_capabilities): Change for short APDU only.
* src/usb-icc.c (USB_BUF_SIZE): Define here (was in gnuk.h).
(struct ep_in, epi_init, struct ep_out, epo_init, endpoint_out)
(endpoint_in, icc_state_p, struct ccid, APDU_STATE_WAIT_COMMAND)
(APDU_STATE_COMMAND_CHAINING, APDU_STATE_COMMAND_RECEIVED)
(APDU_STATE_RESULT, APDU_STATE_RESULT_GET_RESPONSE, ccid_reset)
(ccid_init, CMD_APDU_HEAD_SIZE, apdu_init, notify_tx, no_buf)
(set_sw1sw2, get_sw1sw2, notify_icc, end_icc_rx, end_abdata)
(end_cmd_apdu_head, end_nomore_data, end_cmd_apdu_data)
(nomore_data, INS_GET_RESPONSE, icc_cmd_apdu_data, icc_abdata)
(icc_send_data_block_0x9000, icc_send_data_block_gr, ccid): New.
(icc_data_size, icc_seq, icc_next_p, icc_chain_p, icc_tx_size)
(icc_thread, icc_state, gpg_thread, ICC_RESPONSE_MSG_DATA_SIZE):
Remove.
(EP1_IN_Callback): Rewrite using epi.
(EP2_OUT_Callback): Rewrite using epo.
(icc_prepare_receive): Rewrite using epo and struct ccid.
(ATR): Change ofr short APDU only.
(icc_error, icc_power_on, icc_send_status, icc_power_off)
(icc_send_data_block, icc_send_params, icc_handle_data)
(icc_handle_timeout, USBthread): Rewrite using struct ccid.
* src/usb_desc.c (gnukConfigDescriptor): dwFeatures: Short APDU
level, dwMaxCCIDMessageLength: 271.
* src/usb_lld.c (usb_lld_to_pmabuf, usb_lld_from_pmabuf): New.
* src/usb_lld.h (usb_lld_txcpy, void usb_lld_write) Use
usb_lld_to_pmabuf.
(usb_lld_rxcpy): Use usb_lld_from_pmabuf.
* src/stmusb.mk (usb_mem.c): Remove.
* gnuk_put_binary.py (cmd_select_openpgp): No response APDU data.
(cmd_verify, cmd_write_binary): Send short APDU.
(__main__): Remove RANDOM_NUMBER_BITS support.
Bug fix for CERTDO_SUPPORT.
* src/gnuk.ld.in: Add missing alignment for _data_pool (when no
CERTDO_SUPPORT).
2012-01-19 Niibe Yutaka <gniibe@fsij.org>
* src/usb-icc.c (icc_handle_data): Handle the case when it only
sends 0x90 and 0x00 correctly.
* src/openpgp-do.c (gpg_do_get_data): Fix res_apdu_data_len.
2012-01-18 Niibe Yutaka <gniibe@fsij.org>
Clean up API between application layer and CCID layer.
* tool/gnuk_put_binary.py, gnuk_put_binary_libusb.py: Don't append
0x9000 at the data, any more.
* src/usb-icc.c (icc_data_size, icc_buffer, icc_seq): Make them
internal.
(res_APDU_size, res_APDU_pointer): Removed.
(icc_handle_data, USBthread): Follow new API of struct apdu.
* src/call-rsa.c (rsa_sign, rsa_decrypt): Likewise.
* src/openpgp.c (CLS, INS, P1, P2): New.
(set_res_apdu, cmd_verify, cmd_change_password)
(cmd_reset_user_password, cmd_put_data, cmd_pgp_gakp)
(cmd_read_binary, cmd_select_file, cmd_pso)
(cmd_internal_authenticate, cmd_update_binary, cmd_write_binary)
(process_command_apdu, GPGthread): Follow new API of struct apdu.
* src/openpgp-do.c (gpg_do_get_data, gpg_do_public_key): Follow
new API of struct apdu.
* src/gnuk.h (struct apdu, apdu): New.
(cmd_APDU, icc_data_size, cmd_APDU_size, icc_buffer): Removed.
(res_APDU, res_APDU_size): Use members of struct apdu.
2012-01-16 Niibe Yutaka <gniibe@fsij.org>
Adopt new USB API.
* src/usb_msc.c (usb_start_transmit): Use usb_lld_write.
(EP6_IN_Callback): Use usb_lld_tx_data_len and usb_lld_write.
(usb_start_receive): Use usb_lld_rx_enable.
(EP7_OUT_Callback): Use usb_lld_rx_data_len, usb_lld_rxcpy
and usb_lld_rx_enable
(msc_handle_command): Use usb_lld_stall_rx and usb_lld_stall_tx.
* src/usb_lld.h (usb_lld_stall_tx, usb_lld_stall_rx)
(usb_lld_tx_data_len): New.
* src/main.c (STDOUTthread): Use usb_lld_write.
* src/usb-icc.c (EP1_IN_Callback, icc_error, icc_power_on)
(icc_send_status, icc_send_data_block, icc_send_params): Use
usb_lld_write (was: USB_SIL_Write).
(EP2_OUT_Callback): Use usb_lld_rx_data_len, usb_lld_rxcpy,
and usb_lld_rx_enable (was: USB_SIL_Read and SetEPRxValid).
(icc_prepare_receive): Use usb_lld_rx_enable.
* src/stmusb.mk (STMUSBSRC): Dont' include usb_sil.c.
* src/usb_lld.h (usb_lld_txcpy, usb_lld_tx_enable)
(usb_lld_write, usb_lld_rx_enable, usb_lld_rx_data_len)
(usb_lld_rxcpy): New.
* src/usb_prop.c (SetEPRxCount_allocated_size): Fix the
implementation. (ST's SetEPRxCount is actually meant to
setup allocated size, which is confusing).
(gnuk_device_init): Don't call USB_SIL_Init.
2012-01-10 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp.c (GPGthread): Allow INS_RESET_RETRY_COUNTER and
INS_PUT_DATA for pinentry targets.
2012-01-05 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_select_file): Check DF name.
* tool/pinpadtest.py: Rename from pinpad-test.py.
2011-12-28 Niibe Yutaka <gniibe@fsij.org>
* src/usb_prop.c (SetEPRxCount_allocated_size): New.
(gnuk_device_reset): Use SetEPRxCount_allocated_size.
* src/usb_msc.c (usb_start_receive): Don't set RxCount register
here.
* STM32_USB-FS-Device_Driver/src/usb_core.c (Standard_ClearFeature)
(Post0_Process): Don't need to set RxCount register.
* src/usb_prop.c (msc_lun_info) [PINPAD_DND_SUPPORT]: ifdef-out.
* src/usb-icc.c (EP2_OUT_Callback): Fix apdu size == 49 bug,
we don't assume host sends ZLP (But accepts ZLP, just in case).
2011-12-22 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp-do.c (extended_capabilities) [CERTDO_SUPPORT]:
conditionalize.
2011-12-21 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp-do.c (gpg_do_get_data) [CERTDO_SUPPORT]: ifdef out.
* src/gnuk.ld.in (.gnuk_ch_certificate): Only valid
when --enable-certdo.
* src/flash.c (flash_check_blank) [CERTDO_SUPPORT]: ifdef out.
(flash_erase_binary) [CERTDO_SUPPORT]: Likewise.
(flash_write_binary) [CERTDO_SUPPORT]: Likewise.
* src/configure (certdo): New.
(--enable-certdo, --disable-certdo): New options.
Remove cheking for /dev/random.
* src/config.h.in (@CERTDO_DEFINE@): New.
2011-12-20 Niibe Yutaka <gniibe@fsij.org>
* src/usb_msc.c (msc_handle_command): SCSI_START_STOP_UNIT command
with stop/eject/close means cancelling pinentry.
* src/pin-dnd.c (pinpad_finish_entry, parse_directory_sector):
Implement "cancel".
(pinpad_getline): Likewise.
(msc_scsi_stop): New.
2011-12-16 Niibe Yutaka <gniibe@fsij.org>
* tool/gnuk_put_binary_libusb.py (gnuk_token.cmd_select_openpgp):
Fix apdu parameter.
* tool/gnuk_put_binary.py (GnukToken.cmd_select_openpgp): Ditto.
* tool/pinpad-test.py: New.
2011-12-14 Niibe Yutaka <gniibe@fsij.org>
* Version 0.16.
* src/usb_desc.c (gnukStringSerial): Updated.
* boards/STM8S_DISCOVERY/board.h, board.c: Fix for PINPAD_SUPPORT.
* boards/STBEE_MINI/board.h, board.c: Likewise.
* boards/STBEE/board.h, board.c: Likewise.
* boards/FST_01/board.c: Likewise.
2011-12-13 Niibe Yutaka <gniibe@fsij.org>
Add pinpad DND support.
* src/Makefile.in (CSRC) [ENABLE_PINPAD]: Add usb_msc.c.
* src/configure (pinpad): Add dnd support.
* src/gnuk.h [PINPAD_DND_SUPPORT]: Add declarations.
* src/main.c (STDOUTthread): Add PUSH packet.
(main) [PINPAD_DND_SUPPORT]: Call msc_init.
* src/usb_conf.h (EP_NUM): Add the case of PINPAD_DND_SUPPORT.
(ENDP6_TXADDR, ENDP7_RXADDR): New.
(ENDP4_TXADDR, ENDP5_RXADDR): Changed for smaller buffer.
* src/usb_desc.c (gnukConfigDescriptor): Add Mass storage device.
* src/usb_msc.c, src/usb_msc.h, src/pin-dnd.c: New.
* src/usb_prop.c: Include "usb_msc.h".
(gnuk_device_reset): Add initialization of ENDP6 and ENDP7.
(gnuk_device_SetInterface): Add initialization of ENDP6 and ENDP7.
(NUM_INTERFACES): Handle cases for PINPAD_DND_SUPPORT.
(msc_lun_info): New.
(gnuk_setup_with_data, gnuk_setup_with_nodata): Handle standard
request for Mass storage device.
* Virtual_COM_Port/usb_desc.h (VIRTUAL_COM_PORT_DATA_SIZE): Since
there isn't enough hardware buffer, smaller value (was: 64).
* src/ac.c (verify_user_0): Add access argument.
(verify_pso_cds, verify_other, verify_admin_0): Follow the change.
* src/openpgp.c (cmd_change_password): Likewise.
2011-12-08 Niibe Yutaka <gniibe@fsij.org>
* src/usb-icc.c: Not include "usb_desc.h".
* src/usb_endp.c (EP5_OUT_Callback): Fix minor bug.
2011-12-07 Niibe Yutaka <gniibe@fsij.org>
* src/usb_desc.c (gnukDeviceDescriptor): Changed bcdUSB = 1.1.
Gnuk device conforms to USB 2.0 full speed device, but when it was
2.0, some OS informs users, "you can connect the device to 2.0
compliant hub so that it can have better bandwidth", which is not
the case for full speed device.
* src/openpgp.c (GPGthread): Handle bConfirmPIN parameter.
* src/usb-icc.c (icc_handle_data): Pass PC_to_RDR_Secure
information to gpg_thread using memory of cmd_APDU.
2011-12-01 Niibe Yutaka <gniibe@fsij.org>
* src/gnuk.h (EV_PINPAD_INPUT_DONE, EV_NOP, EV_CMD_AVAILABLE)
(EV_VERIFY_CMD_AVAILABLE, EV_MODIFY_CMD_AVAILABLE): New.
* src/usb-icc.c (icc_power_off, icc_handle_data): Use EV_NOP,
EV_CMD_AVAILABLE, EV_VERIFY_CMD_AVAILABLE, and EV_MODIFY_CMD_AVAILABLE.
* src/pin-cir.c (cir_timer_interrupt): Use EV_PINPAD_INPUT_DONE.
* src/pin-dial.c (dial_sw_interrupt, pinpad_getline): Ditto.
(EV_SW_PUSH): Remove.
* src/openpgp.h (GPG_FUNCTION_NOT_SUPPORTED): New.
(GPG_CONDITION_NOT_SATISFIED): New.
* src/openpgp.c (cmd_change_password): Use GPG_FUNCTION_NOT_SUPPORTED.
* src/openpgp.c (cmd_verify, cmd_change_password)
(cmd_reset_user_password, cmd_put_data): Remove pinpad handling...
(GPGthread): ... and implement pinpad handling here.
2011-11-29 Niibe Yutaka <gniibe@fsij.org>
* src/openpgp.c (cmd_put_data) [PINPAD_SUPPORT]: Support pinpad
input (for reset code).
2011-11-24 Niibe Yutaka <gniibe@fsij.org>
* Version 0.15.
* src/usb_desc.c (gnukStringSerial): Updated.
2011-11-22 Niibe Yutaka <gniibe@fsij.org>
* tool/dfuse.py (DFU_STM32.download, DFU_STM32.verify): Support
unaligned write and hole.
2011-11-14 Niibe Yutaka <gniibe@fsij.org>
* boards/FST_01/{mcuconf.h,board.h,board.c}: New.
2011-11-01 Niibe Yutaka <gniibe@fsij.org>
* src/pin-dial.c (pinpad_getline): New.
(pin_main): Remove.
* boards/STBEE_MINI/board.h (TIMx): Define.
boards/STBEE/board.h (TIMx): Ditto.
boards/STM8S_DISCOVERY/board.h: Ditto.
* src/pin-cir.c (pinpad_getline): New.
(cir_timer_interrupt, cir_ext_interrupt): Use TIMx.
(cir_key_is_backspace, cir_key_is_enter, pin_main, pindisp):
Remove.
(cir_codetable_dell_mr425, cir_codetable_aquos)
(cir_codetable_regza, cir_codetable_bravia, ch_is_backspace)
(ch_is_enter, find_char_codetable, hex, cir_getchar): New.
(cir_timer_interrupt): Don't filter out ADDRESS.
* src/openpgp.c (get_pinpad_input): Don't invoke thread,
but just call pinpad_getline.
* src/main.c (display_interaction, display_fatal_code)
(display_status_code, led_blink): New.
(main): Call display_* routine.
(fatal): Notify main thread.
* src/usb_prop.c (gnuk_device_SetConfiguration): Notify main
thread.
* src/pin-cir.c (pindisp): Remove.
* boards/FST_01_00: New (for 8MHz FST-01).
* src/ac.c (calc_md): Fix comparison.
* src/call-rsa.c (RSA_SIGNATURE_LENGTH): Use KEY_CONTENT_LEN.
(rsa_sign, rsa_decrypt): Likewise.
(modulus_calc): Don't assume it's 2048-bit.
* src/ac.c (verify_user_0): Fix for non-initialized PW1.
* src/Makefile.in (MCFLAGS): Override MCFLAGS option for newer
GCC of summon-arm-toolchain to add -mfix-cortex-m3-ldrd.
NOTE: This should not be needed (as -mcpu=cortex-m3 defaults
to -mfix-cortex-m3-ldrd for GCC-proper), but it is needed
to select arm-none-eabi/lib/thumb2/libc.a correctly.
2011-10-14 NIIBE Yutaka <gniibe@fsij.org>
* src/gnuk.ld.in (__main_stack_size__): It's 1KB (was 512 byte).
2011-10-07 NIIBE Yutaka <gniibe@fsij.org>
* Version 0.14.
* src/usb_desc.c (gnukStringSerial): Updated.
* src/random.c (random_init): Call neug_prng_reseed.
2011-10-06 NIIBE Yutaka <gniibe@fsij.org>
* src/Makefile.in (random_bits): Remove.
* src/openpgp.c (GPGthread): Remove unused event message.
* src/main.c (main): Call random_init.
* src/gnuk.ld.in (__process_stack_size__): Fix.
(.gnuk_random): Removed.
* src/flash.c (flash_erase_binary, flash_write_binary): Remove
support of random_byte in flash ROM.
* src/neug.c (adccb): Use old API (was: chEvtSignalFlagsI).
(adccb_err): Remove.
(rng_gen, rng): Add the last argument adccb for adcStartConversion:
This is old API of ADC driver.
(adcgrpcfg): Remove callbacks, add CONT and SWSTART: This is old
API of ADC driver.
(adccb): Remove the first argument: This is old API of ADC driver.
(neug_wait_full): New.
* ChibiOS_2.0.8/os/hal/platforms/STM32/adc_lld.h (ADC_SAMPLE_1P5):
Add (from new API).
* src/random.c (random_init): New.
(random_bytes_get, random_bytes_free, get_salt): Use NeuG.
* src/Makefile.in (CSRC): Add neug.c.
* src/neug.c: New. Verbatim copy of NeuG/src/random.c.
* boards/common/mcuconf-common.h (USE_STM32_ADC1): TRUE for NewG RNG.
* src/chconf.h (CH_USE_SEMAPHORES): TRUE as ADC driver requires it.
* src/halconf.h (CH_HAL_USE_ADC); TRUE for NewG RNG.
2011-07-22 NIIBE Yutaka <gniibe@fsij.org>
* boards/OLIMEX_STM32_H103/board.h (BOARD_NAME): Fixed.
* boards/STBEE_MINI/mcuconf.h: Added missing include of
mcuconf-common.h.
2011-07-04 NIIBE Yutaka <gniibe@fsij.org>
* ChibiOS_2.0.8/os/ports/GCC/ARMCMx/chcore_v7m.c
(_port_irq_epilogue, _port_switch_from_isr): Apply a patch of 2.2.6.
* ChibiOS_2.0.8/os/hal/platforms/STM32/adc_lld.h: Apply a patch of
ADC from the branch of ChibiOS_2.0.X.
2011-06-15 NIIBE Yutaka <gniibe@fsij.org>
* Version 0.13.

View File

@@ -62,6 +62,20 @@
#define ADC_CHANNEL_SENSOR 16 /**< @brief Internal temperature sensor.*/
#define ADC_CHANNEL_VREFINT 17 /**< @brief Internal reference. */
/**
* @name Sampling rates
* @{
*/
#define ADC_SAMPLE_1P5 0 /**< @brief 1.5 cycles sampling time. */
#define ADC_SAMPLE_7P5 1 /**< @brief 7.5 cycles sampling time. */
#define ADC_SAMPLE_13P5 2 /**< @brief 13.5 cycles sampling time. */
#define ADC_SAMPLE_28P5 3 /**< @brief 28.5 cycles sampling time. */
#define ADC_SAMPLE_41P5 4 /**< @brief 41.5 cycles sampling time. */
#define ADC_SAMPLE_55P5 5 /**< @brief 55.5 cycles sampling time. */
#define ADC_SAMPLE_71P5 6 /**< @brief 71.5 cycles sampling time. */
#define ADC_SAMPLE_239P5 7 /**< @brief 239.5 cycles sampling time. */
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -238,26 +252,51 @@ typedef struct {
/* Driver macros. */
/*===========================================================================*/
/**
* @brief Number of channels in a conversion sequence.
*/
#define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
#define ADC_SQR3_SQ0_N(n) ((n) << 0)
#define ADC_SQR3_SQ1_N(n) ((n) << 5)
#define ADC_SQR3_SQ2_N(n) ((n) << 10)
#define ADC_SQR3_SQ3_N(n) ((n) << 15)
#define ADC_SQR3_SQ4_N(n) ((n) << 20)
#define ADC_SQR3_SQ5_N(n) ((n) << 25)
#define ADC_SQR3_SQ1_N(n) ((n) << 0) /**< @brief 1st channel in seq. */
#define ADC_SQR3_SQ2_N(n) ((n) << 5) /**< @brief 2nd channel in seq. */
#define ADC_SQR3_SQ3_N(n) ((n) << 10) /**< @brief 3rd channel in seq. */
#define ADC_SQR3_SQ4_N(n) ((n) << 15) /**< @brief 4th channel in seq. */
#define ADC_SQR3_SQ5_N(n) ((n) << 20) /**< @brief 5th channel in seq. */
#define ADC_SQR3_SQ6_N(n) ((n) << 25) /**< @brief 6th channel in seq. */
#define ADC_SQR2_SQ6_N(n) ((n) << 0)
#define ADC_SQR2_SQ7_N(n) ((n) << 5)
#define ADC_SQR2_SQ8_N(n) ((n) << 10)
#define ADC_SQR2_SQ9_N(n) ((n) << 15)
#define ADC_SQR2_SQ10_N(n) ((n) << 20)
#define ADC_SQR2_SQ11_N(n) ((n) << 25)
#define ADC_SQR2_SQ7_N(n) ((n) << 0) /**< @brief 7th channel in seq. */
#define ADC_SQR2_SQ8_N(n) ((n) << 5) /**< @brief 8th channel in seq. */
#define ADC_SQR2_SQ9_N(n) ((n) << 10) /**< @brief 9th channel in seq. */
#define ADC_SQR2_SQ10_N(n) ((n) << 15) /**< @brief 10th channel in seq.*/
#define ADC_SQR2_SQ11_N(n) ((n) << 20) /**< @brief 11th channel in seq.*/
#define ADC_SQR2_SQ12_N(n) ((n) << 25) /**< @brief 12th channel in seq.*/
#define ADC_SQR1_SQ13_N(n) ((n) << 0)
#define ADC_SQR1_SQ14_N(n) ((n) << 5)
#define ADC_SQR1_SQ15_N(n) ((n) << 10)
#define ADC_SQR1_SQ16_N(n) ((n) << 15)
#define ADC_SQR1_SQ13_N(n) ((n) << 0) /**< @brief 13th channel in seq.*/
#define ADC_SQR1_SQ14_N(n) ((n) << 5) /**< @brief 14th channel in seq.*/
#define ADC_SQR1_SQ15_N(n) ((n) << 10) /**< @brief 15th channel in seq.*/
#define ADC_SQR1_SQ16_N(n) ((n) << 15) /**< @brief 16th channel in seq.*/
#define ADC_SMPR2_SMP_AN0(n) ((n) << 0) /**< @brief AN0 sampling time. */
#define ADC_SMPR2_SMP_AN1(n) ((n) << 3) /**< @brief AN1 sampling time. */
#define ADC_SMPR2_SMP_AN2(n) ((n) << 6) /**< @brief AN2 sampling time. */
#define ADC_SMPR2_SMP_AN3(n) ((n) << 9) /**< @brief AN3 sampling time. */
#define ADC_SMPR2_SMP_AN4(n) ((n) << 12) /**< @brief AN4 sampling time. */
#define ADC_SMPR2_SMP_AN5(n) ((n) << 15) /**< @brief AN5 sampling time. */
#define ADC_SMPR2_SMP_AN6(n) ((n) << 18) /**< @brief AN6 sampling time. */
#define ADC_SMPR2_SMP_AN7(n) ((n) << 21) /**< @brief AN7 sampling time. */
#define ADC_SMPR2_SMP_AN8(n) ((n) << 24) /**< @brief AN8 sampling time. */
#define ADC_SMPR2_SMP_AN9(n) ((n) << 27) /**< @brief AN9 sampling time. */
#define ADC_SMPR1_SMP_AN10(n) ((n) << 0) /**< @brief AN10 sampling time. */
#define ADC_SMPR1_SMP_AN11(n) ((n) << 3) /**< @brief AN11 sampling time. */
#define ADC_SMPR1_SMP_AN12(n) ((n) << 6) /**< @brief AN12 sampling time. */
#define ADC_SMPR1_SMP_AN13(n) ((n) << 9) /**< @brief AN13 sampling time. */
#define ADC_SMPR1_SMP_AN14(n) ((n) << 12) /**< @brief AN14 sampling time. */
#define ADC_SMPR1_SMP_AN15(n) ((n) << 15) /**< @brief AN15 sampling time. */
#define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18) /**< @brief Temperature Sensor
sampling time. */
#define ADC_SMPR1_SMP_VREF(n) ((n) << 21) /**< @brief Voltage Reference
sampling time. */
/*===========================================================================*/
/* External declarations. */

View File

@@ -107,12 +107,12 @@ void SVCallVector(void) {
}
/**
* @brief Reschedule verification and setup after an IRQ.
* @brief Exception exit redirection to _port_switch_from_isr().
*/
void _port_irq_epilogue(void) {
port_lock_from_isr();
if ((SCB_ICSR & ICSR_RETTOBASE) && chSchIsRescRequiredExI()) {
if ((SCB_ICSR & ICSR_RETTOBASE)) {
register struct extctx *ctxp;
/* Adding an artificial exception return context, there is no need to
@@ -126,7 +126,6 @@ void _port_irq_epilogue(void) {
order to keep the rest of the context switching atomic.*/
return;
}
/* ISR exit without context switching.*/
port_unlock_from_isr();
}
@@ -139,7 +138,8 @@ __attribute__((naked))
#endif
void _port_switch_from_isr(void) {
chSchDoRescheduleI();
if (chSchIsRescRequiredExI())
chSchDoRescheduleI();
asm volatile ("svc #0");
}

3
GNUK_USB_DEVICE_ID Normal file
View File

@@ -0,0 +1,3 @@
# VID:PID bcdDev Product_STRING Vender_STRING
234b:0000 0200 FSIJ USB Token Free Software Initiative of Japan
##########<TAB> ##<TAB> ##########<TAB> #################

115
NEWS
View File

@@ -1,5 +1,120 @@
Gnuk NEWS - User visible changes
* Major changes in Gnuk 0.18
Released 2012-05-15, by NIIBE Yutaka
** New mandatory option '--vidpid' for configure
You must specify USB vendor ID and product ID for Gnuk.
The file GNUK_USB_DEVICE_ID lists valid USB device IDs.
** New tool: gnuk_remove_keys.py
The tool gnuk_remove_keys.py is to remove all keys in Gnuk Token
and reset PW1 and RC (if any).
** New USB stack
Gnuk used to use USB stack of USB-FS-Device_Lib by ST. Now, it has
original implementation. Hopefully, size and quality are improved.
* Major changes in Gnuk 0.17
Released 2012-02-02, by NIIBE Yutaka
** USB CCID/ICCD protocol implementation change
Gnuk now only supports short APDU level exchange, not support.
extended APDU level exchange. Thus, Gnuk could be compatible to older
host side software implementation.
** ISO 7816 SELECT command behavior is somewhat strict now
Old implementations do not check DF name for SELECT command.
This causes some trouble when Gnuk Token is identified as if it were
different card/token. Now, DF name of OpenPGP card is checked.
** USB CCID/ICCD low-level bug is fixed
When the size of command APDU data is just 49, the lower level packet
size is 64. This is maximum size of BULK-OUT transfer packet, and
caused trouble in the past implementations. Example is setting url
(0x5f50) as: http://www.gniibe.org/adpu-string-size-is-just-49
This is because the past implementations expect ZLP (zero length
packet). Now, it has been fixed. You can use any size of string.
** CERT.3 Data Object (0x7f21) is now optional
As there's no valid use case for this data object and it does not
work as current version of GnuPG, this is now optional feature.
You can enable this data object by specifying --enable-certdo at
configure time.
** With DnD pinentry, user can cancel pin input
Now, user can cancel pin input by unmounting device before finishing
DnD.
** New tool: pinpadtest.py
The tool pinpadtest.py is PC/SC test tool for pinentry of pinpad with
OpenPGP card v2.
* Major changes in Gnuk 0.16
Released 2011-12-14, by NIIBE Yutaka
** DnD pinentry support is added and it's default to pinentry support
DnD pinentry support doesn't require any hardware extension, but
emulates mass storage class device of USB. User inputs pass phrase
by "drag and drop"-ing folders using file manager or something.
** Bug fix for VERIFY for CHV2
With no keys, VERIFY command for CHV2 used to fail even if pass phrase
is correct. It was intentional, because CHV2 verification would be
useless with no keys. But there is a corner case for PRIVATE-DOs,
which may requires CHV2 verification. Even though Gnuk doesn't
support any PRIVATE-DOs, it is good to be fixed.
** Changed bcdUSB = 1.1
Gnuk device conforms to USB 2.0 full speed device, but when it was
2.0, some OS informs users, "you can connect the device to 2.0
compliant hub so that it can have better bandwidth", which is not
the case for full speed device.
* Major changes in Gnuk 0.15
Released 2011-11-24, by NIIBE Yutaka
** New targets: FST_01 and FST_01_00
Flying Stone Technology's open hardware, Flying Stone Tiny 01 is
supported.
** Flash writing tool for "DfuSe" is improved
Now, it supports holes and unaligned blocks in hex file.
** Experimental PIN-pad support (by TV controller) change
Now, Gnuk has codetables for conversion from CIR code to ASCII code.
Note that only four controllers (of Dell, Sharp, Sony, and Toshiba)
are supported and tested.
** It is possible for users to keep using OPENPGP_CARD_INITIAL_PW1
With a bug fix of verify_user_0, it's now possible. Although it's not
recommended.
** Important bug fix and a workaround
In version 0.14, __main_stack_size__ (for interrupt handler) was too
small for some cases. This is fixed in 0.15.
In src/Makefile.in, added -mfix-cortex-m3-ldrd for correctly linking C
library for thumb2. This is needed for newer summon-arm-toolchain.
* Major changes in Gnuk 0.14
Released 2011-10-07, by NIIBE Yutaka
** Random number generator change
NeuG, Gniibe's True RNG implementation for STM32F103, has been
integrated to Gnuk. It is not needed to put random number bytes
(generated by host) to Token any more.
* Major changes in Gnuk 0.13
Released 2011-06-15, by NIIBE Yutaka

225
README
View File

@@ -1,21 +1,21 @@
Gnuk - software for GnuPG USB Token
Version 0.13
2011-06-15
Niibe Yutaka
Version 0.18
2012-05-15
Niibe Yutaka
Free Software Initiative of Japan
What's Gnuk?
============
Gnuk is software implementation of a USB token for GNU Privacy Guard.
Gnuk supports OpenPGP card protocol version 2, and it runs on STM32
processor.
Gnuk supports OpenPGP card protocol version 2, and it runs on
STM32F103 processor.
I wish that Gnuk will be a developer's soother who uses GnuPG. I have
been nervous of storing secret key(s) on usual secondary storage.
While I want to work at different places, but it is not the choice for
me to bring a card reader all the time. With Gnuk, this issue will be
There is a solution with OpenPGP card, but it is not the choice for me
to bring a card reader all the time. With Gnuk, this issue will be
solved by a USB token which is small enough.
Please look at the graphics of "gnuk.svg" for the software name. My
@@ -27,21 +27,22 @@ FAQ
===
Q0: How Gnuk USB Token is superior than other solutions (OpenPGP
card 2.0, GPF Crypto Stick, etc) ?
card 2.0, GPF Crypto Stick, etc.) ?
http://www.g10code.de/p-card.html
http://www.privacyfoundation.de/crypto_stick/
A0: IMRHO, not quite. There is no ready-to-use out-of-box product.
(It is welcome for me that some vendor will manufacture Gnuk USB
Token. Even I can help design of hardware, if needed.)
Good points are:
A0: IMRHO, not quite, since there is no ready-to-use out-of-box Gnuk
product yet. (It is welcome for me that some vendor will
manufacture Gnuk USB Token. Even I can help design of hardware,
if needed.)
Good points for Gnuk are:
* If you have skill of electronics and like DIY, you can build
Gnuk Token cheaper (see Q8-A8).
* You can study Gnuk to modify and to enhance. For example, you
can implement your own authentication method with some sensor
such as acceleration sensor.
* It is "of Free Software"; Gnuk is distributed under GPLv3+,
"by Free Software"; Gnuk development requires only Free Software
(GNU Toolchain, Python, etc.),
"by Free Software"; Gnuk development requires only Free Software
(GNU Toolchain, Python, etc.),
"for Free Software"; Gnuk supports GnuPG.
Q1: What kind of key algorithm is supported?
@@ -54,6 +55,8 @@ Q3: What's your recommendation for target board?
A3: Orthodox choice is Olimex STM32-H103.
If you have skill of electronics and like DIY, STM32 part of STM8S
Discovery Kit might be the best choice.
Currently FST-01 (Flying Stone Tiny 01) is under development,
it will be the best choice, hopefully.
Q4: What's version of GnuPG are you using?
A4: In Debian GNU/Linux system, I use gnupg 1.4.11-3 and gnupg-agent
@@ -88,17 +91,32 @@ A9: GnuPG's SCDaemon has problems for handling insertion/removal of
and confirm scdaemon doesn't exist, then,
$ gpg-connect-agent learn /bye
Qa: With GNOME 2, I can't use Gnuk Token for SSH. How can we use it for SSH?
Aa: You need to deactivate seahorse-agent and gnome-keyring, but use
gpg-agant for the role of ssh-agent. For gnome-keyring please do:
$ gconftool-2 --type bool --set /apps/gnome-keyring/daemon-components/ssh false
Qb: With GNOME 3, I can't use Gnuk Token at all. Why?
Ab: That's because gnome-keyring-daemon interferes GnuPG. Type:
$ gnome-session-properties
and at the tab of "Startup Programs", disable check buttons for
"GPG Password Agent" and "SSH Key Agent".
Qc: Do you know a good SWD debugger to connect FST-01 or something?
Ac: Perhaps, you can use a part of STM32F4 Discovery Kit as SWD
debugger. It seems that there is a free software tool for that.
Release notes
=============
This is fourteenth release of Gnuk. While it works well for specific
This is nineteenth release of Gnuk. In this release, the usage of USB
device ID by FSIJ is clarified. While it works well for specific
usages and it is considered stable, it is still somewhat experimental.
Note that you need to write random bits after installation of gnuk
executable to the chip. This procedure is required to share a single
executable among multiple devices.
Tested features are:
* Personalization of the card
@@ -114,29 +132,26 @@ Tested features are:
* Changing value of password status bytes (0x00C4): forcesig
* Verify with pin pad
* Modify with pin pad
* Card holder certificate
* Removal of keys (Overriding key import is not supported,
but you can remove all keys to import again).
It is known not-working well:
* For some version of kernel and libccid, --enable-debug can't
work well. Please disable DEBUG option if it doesn't work well.
* Card holder certificate
It is implemented in Gnuk side. But its size matters (>
1KB). GnuPG cannot handle a data object of large size with
PC/SC backend. Specifically, handle_transmit function in
pcsc-wrapper.c uses the buffer of size 1024-byte.
work well. Please make sure to disable DEBUG option if it
doesn't work well.
Not supported feature(s):
* Overriding key import. You need to remove all keys first.
* Key generation
* Key generation on device side
Targets
=======
We use Olimex STM32-H103 board. We also use STM32 part of STM8S
Discovery Kit.
We use Olimex STM32-H103 board and Flying Stone Tiny 01 (FST-01). We
also use STM32 part of STM8S Discovery Kit.
With DfuSe support, CQ STARM, STBee, and STBee Mini are also our
targets. But those targets with DfuSe are basically not for normal
@@ -159,6 +174,16 @@ Another PIN-pad support is connecting rotary encoder, push switch and
7-segment LED display. Both of PIN verification and PIN modification
are supported for this circuit extension.
Recently, "DnDpinentry" support is added. This is using usual file
manager for pinentry. User does "drag and drop" folders and it will
be pin entry. This feature doesn't require any additional hardware.
See doc/settings-for-DnDpinentry for your desktop configuration.
Note that you need pinpad support for GnuPG, it's currently in the
master branch of GnuPG git repository at git.gnupg.org, and it's under
evaluation. When it will be considered stable, it will be put onto
stable branch.
Souce code
==========
@@ -179,8 +204,8 @@ The author(s) of Gnuk expect users of Gnuk will be able to access the
source code of Gnuk, so that users can study the code and can modify
if needed. This doesn't mean person who has a USB Token by Gnuk
should be able to acess everything on the Token, regardless of its
protections. Private keys, random bytes, and other information should
be protected properly.
protections. Private keys, and other information should be protected
properly.
External source code
@@ -203,22 +228,56 @@ Gnuk is distributed with external source code.
The file include/polarssl/bn_mul.h is heavily modified for ARM
Cortex-M3.
* STM32_USB-FS-Device_Driver/ -- a part of USB-FS-Device_Lib
* Virtual_COM_Port/ -- a part of USB-FS-Device_Lib
STM32F10x USB Full Speed Device Library (USB-FS-Device_Lib)
is a STM32F10x library for USB functionality.
USB vendor ID and product ID (USB device ID)
============================================
I took Libraries/STM32_USB-FS-Device_Driver and
Project/Virtual_COM_Port in STM32_USB-FS-Device_Lib distribution.
See http://www.st.com/ for detail.
When you have a vender ID and assign a product ID for Gnuk, edit the
file GNUK_USB_DEVICE_ID and add an entry for yours. In this case,
please contact Niibe, so that it is listed to the file in the official
release of source code.
When you are modifing Gnuk and installing the binary to device, you
should replace "FSIJ" in the string gnukStringSerial (usb_desc.c) to
yours, so that the device will say it's modified version by device
serial number.
FSIJ allows you to use USB device ID of FSIJ (234b:0000) for devices
with Gnuk under one of following conditions:
* For everyone for experimental purpose:
- You must not distribute a binary with FSIJ's USB device ID, but
must use the binary by yourself only for your experiment. Note
that "Distributing binary" includes distributing a device which
holds the binary.
* For general individuals:
- You must use your Gnuk device with a card serial number which is
*not* by FSIJ. Easy one would be a card serial number generated
by chip unique ID.
* For individuals with explicit permission from FSIJ.
- You should have an assigned card serial number by FSIJ,
please use that number for your device.
(There a file 'GNUK_SERIAL_NUMBER' in the official release.)
FSIJ could permit companies or business entities to use USB device ID
of FSIJ for devices with unmodified version of Gnuk, provided they
support Free Software and respect users' freedom for computing.
Please ask FSIJ for permission.
Otherwise, companies which want to distribute Gnuk devices, please use
your own USB vendor ID and product ID. When you modify Gnuk, please
replace "FSIJ" in the string gnukStringSerial (usb_desc.c) to yours.
Host Requirements
=================
For GNU/Linux, libccid version >= 1.3.11 is required.
libccid version == 1.3.9 is known not working well by the issue [r4235].
For GNU/Linux, libccid version >= 1.3.11 is recommended.
I think that it should not be requirment but the kernel version of my use is:
Linux version 2.6.32-5-686 (Debian 2.6.32-18) (ben@decadent.org.uk) (gcc version 4.3.5 (Debian 4.3.5-2) ) #1 SMP Sat Jul 24 02:27:10 UTC 2010
@@ -232,8 +291,24 @@ How to compile
You need GNU toolchain and newlib for 'arm-none-eabi' target.
See http://github.com/uwehermann/summon-arm-toolchain/ for preparation
of GNU Toolchain for 'arm-none-eabi' target.
See http://github.com/esden/summon-arm-toolchain/ (which includes fix
of binutils-2.21.1) for preparation of GNU Toolchain for
'arm-none-eabi' target.
# Note that we need to link correct C library (for string functions).
# For this purpose, Makefile.in contains following line:
#
# MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
#
# This should not be needed (as -mcpu=cortex-m3 means
# -mfix-cortex-m3-ldrd), but in practice it is needed for
# the configuration of patch-gcc-config-arm-t-arm-elf.diff in
# summon-arm-toolchain.
#
# In ChibiOS_2.0.8/os/ports/GCC/ARM/rules.mk, it specifies
# -mno-thumb-interwork option. This means that you should not
# link C library which contains ARM (not Thumb) code.
Change directory to `src':
@@ -241,7 +316,11 @@ Change directory to `src':
Then, run `configure':
$ ./configure
$ ./configure --vidpid=<VID:PID>
Here, you need to specify USB vendor ID and product ID. For FSIJ's,
it's: --vidpid=234b:0000 . Please read section 'USB vendor ID and
product ID' above.
Type:
@@ -270,6 +349,36 @@ Then, with another terminal, type following to write "gnuk.elf" to Flash ROM:
$
Flying Stone Tiny 01
--------------------
If you are using Flying Stone Tiny 01, you need a SWD writer. I am
using revision 946 of Simon Qian's Versaloon.
svn checkout -r 946 http://vsprog.googlecode.com/svn/trunk/
For OpenOCD, we need unofficial patch.
See the article of Versaloon Forum:
http://www.versaloon.com/bbs/viewtopic.php?p=16179
Type following to invoke OpenOCD:
$ openocd -f interface/vsllink.cfg -c "transport select swd" -c "swd_mode 2" -f target/stm32f1x.cfg
Then, with another terminal, type following to write "gnuk.elf" to Flash ROM:
$ telnet localhost 4444
> reset halt
> flash write_image erase gnuk.elf
> reset
> exit
$
STM8S Discovery Kit
-------------------
@@ -341,19 +450,7 @@ How to configure
You need python and pyscard (python-pyscard package in Debian) or
PyUSB (python-usb package in Debian).
(1) In the 'src' directory, type
$ make random_bits
In this process, it takes time for the command of
dd if=/dev/random bs=1 of=random_bits count=1024
Don't just wait, but do some other works on your PC.
/dev/random needs entropy to finish.
(2) [pyscard] Stop scdaemon
(1) [pyscard] Stop scdaemon
[PyUSB] Stop the pcsc daemon.
If scdaemon is running, please kill it, or you will get "Smartcard
@@ -366,17 +463,7 @@ In case of PyUSB tool, you need to stop pcscd.
# /etc/init.d/pcscd stop
(3) Write the random bits to the device
Connect your board to USB port of your PC. And invoke gnuk_put_binary.py:
$ ../tool/gnuk_put_binary.py -r random_bits
random_bits: 1024
Updating random bits
...
(4) [Optional] Write fixed serial number
(2) [Optional] Write fixed serial number
If you use fixed serial number in the file 'GNUK_SERIAL_NUMBER', you can do:
@@ -384,7 +471,7 @@ If you use fixed serial number in the file 'GNUK_SERIAL_NUMBER', you can do:
Writing serial number
...
(5) [Optional] Write card holder certificate
(3) [Optional] Write card holder certificate
If you have card holder certificate binary file, you can do:

View File

@@ -1,258 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : otgd_fs_cal.h
* Author : STMicroelectronics
* Version : V3.1.1
* Date : 04/07/2010
* Description : Header of OTG FS Device Core Access Layer interface.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifndef __OTG_CORE_H__
#define __OTG_CORE_H__
#ifdef STM32F10X_CL
#include "stm32f10x.h"
#include "usb_type.h"
#if defined ( __CC_ARM )
#define __packed __packed /*!< packing keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __packed __packed /*!< packing keyword for IAR Compiler */
#elif defined ( __GNUC__ )
#define __packed __attribute__ ((__packed__)) /*!< packing keyword for GNU Compiler */
#elif defined ( __TASKING__ ) /*!< packing keyword for TASKING Compiler */
#define __packed
#endif /* __CC_ARM */
/*******************************************************************************
define and types
*******************************************************************************/
#define DEVICE_MODE_ENABLED
#ifndef NULL
#define NULL ((void *)0)
#endif
#define DEV_EP_TX_DIS 0x0000
#define DEV_EP_TX_STALL 0x0010
#define DEV_EP_TX_NAK 0x0020
#define DEV_EP_TX_VALID 0x0030
#define DEV_EP_RX_DIS 0x0000
#define DEV_EP_RX_STALL 0x1000
#define DEV_EP_RX_NAK 0x2000
#define DEV_EP_RX_VALID 0x3000
/***************** GLOBAL DEFINES ***************************/
#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
#define GAHBCFG_GLBINT_ENABLE 1
#define GAHBCFG_INT_DMA_BURST_SINGLE 0
#define GAHBCFG_INT_DMA_BURST_INCR 1
#define GAHBCFG_INT_DMA_BURST_INCR4 3
#define GAHBCFG_INT_DMA_BURST_INCR8 5
#define GAHBCFG_INT_DMA_BURST_INCR16 7
#define GAHBCFG_DMAENABLE 1
#define GAHBCFG_TXFEMPTYLVL_EMPTY 1
#define GAHBCFG_TXFEMPTYLVL_HALFEMPTY 0
#define GRXSTS_PKTSTS_IN 2
#define GRXSTS_PKTSTS_IN_XFER_COMP 3
#define GRXSTS_PKTSTS_DATA_TOGGLE_ERR 5
#define GRXSTS_PKTSTS_CH_HALTED 7
#define DEVICE_MODE 0
#define HOST_MODE 1
/***************** DEVICE DEFINES ***************************/
#define DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ 0
#define DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ 1
#define DSTS_ENUMSPD_LS_PHY_6MHZ 2
#define DSTS_ENUMSPD_FS_PHY_48MHZ 3
#define DCFG_FRAME_INTERVAL_80 0
#define DCFG_FRAME_INTERVAL_85 1
#define DCFG_FRAME_INTERVAL_90 2
#define DCFG_FRAME_INTERVAL_95 3
#define DEP0CTL_MPS_64 0
#define DEP0CTL_MPS_32 1
#define DEP0CTL_MPS_16 2
#define DEP0CTL_MPS_8 3
#define EP_SPEED_LOW 0
#define EP_SPEED_FULL 1
#define EP_SPEED_HIGH 2
#define EP_TYPE_CTRL 0
#define EP_TYPE_ISOC 1
#define EP_TYPE_BULK 2
#define EP_TYPE_INTR 3
#define STS_GOUT_NAK 1
#define STS_DATA_UPDT 2
#define STS_XFER_COMP 3
#define STS_SETUP_COMP 4
#define STS_SETUP_UPDT 6
typedef enum {
USB_OTG_OK,
USB_OTG_FAIL
}USB_OTG_Status;
typedef struct USB_OTG_hc
{
uint8_t hc_num;
uint8_t dev_addr ;
uint8_t ep_num;
uint8_t ep_is_in;
uint8_t speed;
uint8_t ep_type;
uint16_t max_packet;
uint8_t data_pid;
uint16_t multi_count;
uint8_t *xfer_buff;
uint32_t xfer_len;
}
USB_OTG_HC , *PUSB_OTG_HC;
typedef struct USB_OTG_ep
{
uint8_t num;
uint8_t is_in;
uint32_t tx_fifo_num;
uint32_t type;
uint8_t data_pid_start;
uint8_t even_odd_frame;
uint32_t maxpacket;
uint8_t *xfer_buff;
uint32_t xfer_len;
uint32_t xfer_count;
}
USB_OTG_EP , *PUSB_OTG_EP;
/********************************************************************************
MACRO'S
********************************************************************************/
#define CLEAR_IN_EP_INTR(epnum,intr) \
diepint.d32=0; \
diepint.b.intr = 1; \
WRITE_REG32(&core_regs.inep_regs[epnum]->dev_in_ep_int,diepint.d32);
#define CLEAR_OUT_EP_INTR(epnum,intr) \
doepint.d32=0; \
doepint.b.intr = 1; \
WRITE_REG32(&core_regs.outep_regs[epnum]->dev_out_ep_int,doepint.d32);
#define READ_REG32(reg) (*(__IO uint32_t *)reg)
#define WRITE_REG32(reg,value) (*(__IO uint32_t *)reg = value)
#define MODIFY_REG32(reg,clear_mask,set_mask) \
WRITE_REG32(reg, (((READ_REG32(reg)) & ~clear_mask) | set_mask ) )
#define uDELAY(usec) udelay(usec)
#define mDELAY(msec) uDELAY(msec * 1000)
#define _OTGD_FS_GATE_PHYCLK *(__IO uint32_t*)(0x50000E00) = 0x03
#define _OTGD_FS_UNGATE_PHYCLK *(__IO uint32_t*)(0x50000E00) = 0x00
/*******************************************************************************
this can be changed for real time base
*******************************************************************************/
static void udelay (const uint32_t usec)
{
uint32_t count = 0;
const uint32_t utime = usec * 10;
do
{
if ( ++count > utime )
{
return ;
}
}
while (1);
}
/********************************************************************************
EXPORTED FUNCTIONS FROM THE OTGD_FS_CAL LAYER
********************************************************************************/
USB_OTG_Status OTGD_FS_CoreInit(void);
USB_OTG_Status OTGD_FS_SetAddress(uint32_t BaseAddress);
USB_OTG_Status OTGD_FS_EnableGlobalInt(void);
USB_OTG_Status OTGD_FS_DisableGlobalInt(void);
USB_OTG_Status USB_OTG_CoreInitHost(void);
USB_OTG_Status USB_OTG_EnableHostInt(void);
USB_OTG_Status USB_OTG_DisableHostInt(void);
void* OTGD_FS_ReadPacket(uint8_t *dest, uint16_t bytes);
USB_OTG_Status OTGD_FS_WritePacket(uint8_t *src, uint8_t ch_ep_num, uint16_t bytes);
USB_OTG_Status USB_OTG_HcInit(USB_OTG_HC *hc);
USB_OTG_Status USB_OTG_StartXfer(USB_OTG_HC *hc);
uint32_t USB_OTG_ResetPort( void);
uint32_t USB_OTG_ReadHPRT0(void);
uint32_t OTGD_FS_ReadDevAllInEPItr(void);
uint32_t OTGD_FS_ReadCoreItr(void);
uint32_t OTGD_FS_ReadOtgItr (void);
uint32_t USB_OTG_ReadHostAllChannels_intr (void);
uint8_t IsHostMode(void);
uint8_t IsDeviceMode(void);
USB_OTG_Status USB_OTG_HcInit(USB_OTG_HC *hc);
USB_OTG_Status USB_OTG_HcHalt(uint8_t hc_num);
USB_OTG_Status OTGD_FS_FlushTxFifo (uint32_t num);
USB_OTG_Status OTGD_FS_FlushRxFifo (void);
USB_OTG_Status OTGD_FS_SetHostMode (void);
USB_OTG_Status OTGD_FS_PhyInit(void);
USB_OTG_Status USB_OTG_HcStartXfer(USB_OTG_HC *hc);
USB_OTG_Status OTGD_FS_CoreInitDev (void);
USB_OTG_Status OTGD_FS_EnableDevInt(void);
USB_OTG_Status OTGD_FS_EP0Activate(void);
USB_OTG_Status OTGD_FS_EPActivate(USB_OTG_EP *ep);
USB_OTG_Status OTGD_FS_EPDeactivate(USB_OTG_EP *ep);
USB_OTG_Status OTGD_FS_EPStartXfer(USB_OTG_EP *ep);
USB_OTG_Status OTGD_FS_EP0StartXfer(USB_OTG_EP *ep);
USB_OTG_Status OTGD_FS_EPSetStall(USB_OTG_EP *ep);
USB_OTG_Status OTGD_FS_EPClearStall(USB_OTG_EP *ep);
uint32_t OTGD_FS_ReadDevAllOutEp_itr(void);
uint32_t OTGD_FS_ReadDevOutEP_itr(USB_OTG_EP *ep);
uint32_t OTGD_FS_ReadDevAllInEPItr(void);
uint32_t OTGD_FS_Dev_GetEPStatus(USB_OTG_EP *ep);
void OTGD_FS_Dev_SetEPStatus(USB_OTG_EP *ep, uint32_t Status);
void OTGD_FS_Dev_SetRemoteWakeup(void);
void OTGD_FS_Dev_ResetRemoteWakeup(void);
#endif /* STM32F10X_CL */
#endif
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,121 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : otg_dev.h
* Author : STMicroelectronics
* Version : V3.1.1
* Date : 04/07/2010
* Description : linking defines
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __OTG_DEV_H__
#define __OTG_DEV_H__
#ifdef STM32F10X_CL
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "usb_type.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Endpoint types */
#define OTG_DEV_EP_TYPE_CONTROL 0
#define OTG_DEV_EP_TYPE_ISOC 1
#define OTG_DEV_EP_TYPE_BULK 2
#define OTG_DEV_EP_TYPE_INT 3
/* Endpoint Addresses (w/direction) */
#define EP0_OUT 0x00
#define EP0_IN 0x80
#define EP1_OUT 0x01
#define EP1_IN 0x81
#define EP2_OUT 0x02
#define EP2_IN 0x82
#define EP3_OUT 0x03
#define EP3_IN 0x83
/*-*-*-*-*-*-*-*-*-* Replace the usb_regs.h defines -*-*-*-*-*-*-*-*-*-*-*-*-*/
/* endpoints enumeration */
#define ENDP0 ((uint8_t)0)
#define ENDP1 ((uint8_t)1)
#define ENDP2 ((uint8_t)2)
#define ENDP3 ((uint8_t)3)
#define ENDP4 ((uint8_t)4)
#define ENDP5 ((uint8_t)5)
#define ENDP6 ((uint8_t)6)
#define ENDP7 ((uint8_t)7)
/* EP Transmit status defines */
#define EP_TX_DIS DEV_EP_TX_DIS) /* EndPoint TX DISabled */
#define EP_TX_STALL DEV_EP_TX_STALL /* EndPoint TX STALLed */
#define EP_TX_NAK DEV_EP_TX_NAK /* EndPoint TX NAKed */
#define EP_TX_VALID DEV_EP_TX_VALID /* EndPoint TX VALID */
/* EP Transmit status defines */
#define EP_RX_DIS DEV_EP_RX_DIS /* EndPoint RX DISabled */
#define EP_RX_STALL DEV_EP_RX_STALL /* EndPoint RX STALLed */
#define EP_RX_NAK DEV_EP_RX_NAK /* EndPoint RX NAKed */
#define EP_RX_VALID DEV_EP_RX_VALID /* EndPoint RX VALID */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Exported macro ------------------------------------------------------------*/
#define _GetEPTxStatus(bEpNum) ((uint16_t)OTG_DEV_GetEPTxStatus(bEpNum))
#define _GetEPRxStatus(bEpNum) ((uint16_t)OTG_DEV_GetEPRxStatus(bEpNum))
#define _SetEPTxStatus(bEpNum,wState) (OTG_DEV_SetEPTxStatus(bEpNum, wState))
#define _SetEPRxStatus(bEpNum,wState) (OTG_DEV_SetEPRxStatus(bEpNum, wState))
#define _SetEPTxValid(bEpNum) (OTG_DEV_SetEPTxStatus(bEpNum, EP_TX_VALID))
#define _SetEPRxValid(bEpNum) (OTG_DEV_SetEPRxStatus(bEpNum, EP_RX_VALID))
#define _GetTxStallStatus(bEpNum) (OTG_DEV_GetEPTxStatus(bEpNum) == EP_TX_STALL)
#define _GetRxStallStatus(bEpNum) (OTG_DEV_GetEPRxStatus(bEpNum) == EP_RX_STALL)
/* Define the callbacks for updating the USB state machine */
#define OTGD_FS_DEVICE_RESET Device_Property.Reset()
/* Exported define -----------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void OTG_DEV_Init(void);
void OTG_DEV_EP_Init(uint8_t bEpAdd, uint8_t bEpType, uint16_t wEpMaxPackSize);
void OTG_DEV_SetEPRxStatus(uint8_t bEpnum, uint32_t status);
void OTG_DEV_SetEPTxStatus(uint8_t bEpnum, uint32_t status);
uint32_t OTG_DEV_GetEPRxStatus(uint8_t bEpnum);
uint32_t OTG_DEV_GetEPTxStatus(uint8_t bEpnum);
void USB_DevDisconnect(void);
void USB_DevConnect(void);
/*-*-*-*-*-*-*-*-*-* Replace the usb_regs.h prototypes *-*-*-*-*-*-*-*-*-*-*-*/
void SetEPTxStatus(uint8_t bEpNum, uint16_t wState);
void SetEPRxStatus(uint8_t bEpNum, uint16_t wState);
uint16_t GetEPTxStatus(uint8_t bEpNum);
uint16_t GetEPRxStatus(uint8_t bEpNum);
void SetEPTxValid(uint8_t bEpNum);
void SetEPRxValid(uint8_t bEpNum);
uint16_t GetTxStallStatus(uint8_t bEpNum);
uint16_t GetRxStallStatus(uint8_t bEpNum);
void SetEPTxCount(uint8_t bEpNum, uint16_t wCount);
void SetEPRxCount(uint8_t bEpNum, uint16_t wCount);
uint16_t ToWord(uint8_t, uint8_t);
uint16_t ByteSwap(uint16_t);
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#endif /* STM32F10X_CL */
#endif /* __OTG_DEV_H__ */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,54 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : otgd_fs_int.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Endpoint interrupt's service routines prototypes.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INT_H
#define __USB_INT_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#ifdef STM32F10X_CL
/* Interrupt Handlers functions */
uint32_t OTGD_FS_Handle_ModeMismatch_ISR(void);
uint32_t OTGD_FS_Handle_Sof_ISR(void);
uint32_t OTGD_FS_Handle_RxStatusQueueLevel_ISR(void);
uint32_t OTGD_FS_Handle_NPTxFE_ISR(void);
uint32_t OTGD_FS_Handle_GInNakEff_ISR(void);
uint32_t OTGD_FS_Handle_GOutNakEff_ISR(void);
uint32_t OTGD_FS_Handle_EarlySuspend_ISR(void);
uint32_t OTGD_FS_Handle_USBSuspend_ISR(void);
uint32_t OTGD_FS_Handle_UsbReset_ISR(void);
uint32_t OTGD_FS_Handle_EnumDone_ISR(void);
uint32_t OTGD_FS_Handle_IsoOutDrop_ISR(void);
uint32_t OTGD_FS_Handle_EOPF_ISR(void);
uint32_t OTGD_FS_Handle_EPMismatch_ISR(void);
uint32_t OTGD_FS_Handle_InEP_ISR(void);
uint32_t OTGD_FS_Handle_OutEP_ISR(void);
uint32_t OTGD_FS_Handle_IncomplIsoIn_ISR(void);
uint32_t OTGD_FS_Handle_IncomplIsoOut_ISR(void);
uint32_t OTGD_FS_Handle_Wakeup_ISR(void);
#endif /* STM32F10X_CL */
/* External variables --------------------------------------------------------*/
#endif /* __USB_INT_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,87 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : otgd_fs_pcd.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Header file of the High Layer device mode interface and
* wrapping layer
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifndef __USB_OTG_PCD_H__
#define __USB_OTG_PCD_H__
#include "otgd_fs_regs.h"
#define MAX_EP0_SIZE 0x40
#define MAX_PACKET_SIZE 0x400
#define USB_ENDPOINT_XFER_CONTROL 0
#define USB_ENDPOINT_XFER_ISOC 1
#define USB_ENDPOINT_XFER_BULK 2
#define USB_ENDPOINT_XFER_INT 3
#define USB_ENDPOINT_XFERTYPE_MASK 3
/********************************************************************************
ENUMERATION TYPE
********************************************************************************/
enum usb_device_speed {
USB_SPEED_UNKNOWN = 0,
USB_SPEED_LOW, USB_SPEED_FULL,
USB_SPEED_HIGH
};
/********************************************************************************
Data structure type
********************************************************************************/
typedef struct usb_ep_descriptor
{
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
}
EP_DESCRIPTOR , *PEP_DESCRIPTOR;
/********************************************************************************
USBF LAYER UNION AND STRUCTURES
********************************************************************************/
typedef struct USB_OTG_USBF
{
USB_OTG_EP ep0;
uint8_t ep0state;
USB_OTG_EP in_ep[ MAX_TX_FIFOS - 1];
USB_OTG_EP out_ep[ MAX_TX_FIFOS - 1];
}
USB_OTG_PCD_DEV , *USB_OTG_PCD_PDEV;
/********************************************************************************
EXPORTED FUNCTION FROM THE USB_OTG LAYER
********************************************************************************/
void OTGD_FS_PCD_Init(void);
void OTGD_FS_PCD_DevConnect (void);
void OTGD_FS_PCD_DevDisconnect (void);
void OTGD_FS_PCD_EP_SetAddress (uint8_t address);
uint32_t OTGD_FS_PCD_EP_Open(EP_DESCRIPTOR *epdesc);
uint32_t OTGD_FS_PCD_EP_Close ( uint8_t ep_addr);
uint32_t OTGD_FS_PCD_EP_Read ( uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len);
uint32_t OTGD_FS_PCD_EP_Write ( uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len);
uint32_t OTGD_FS_PCD_EP_Stall (uint8_t epnum);
uint32_t OTGD_FS_PCD_EP_ClrStall (uint8_t epnum);
uint32_t OTGD_FS_PCD_EP_Flush (uint8_t epnum);
uint32_t OTGD_FS_PCD_Handle_ISR(void);
USB_OTG_EP* OTGD_FS_PCD_GetOutEP(uint32_t ep_num) ;
USB_OTG_EP* OTGD_FS_PCD_GetInEP(uint32_t ep_num);
void OTGD_FS_PCD_EP0_OutStart(void);
#endif
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@@ -1,243 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_core.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Standard protocol processing functions prototypes
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CORE_H
#define __USB_CORE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _CONTROL_STATE
{
WAIT_SETUP, /* 0 */
SETTING_UP, /* 1 */
IN_DATA, /* 2 */
OUT_DATA, /* 3 */
LAST_IN_DATA, /* 4 */
LAST_OUT_DATA, /* 5 */
WAIT_STATUS_IN, /* 7 */
WAIT_STATUS_OUT, /* 8 */
STALLED, /* 9 */
PAUSE /* 10 */
} CONTROL_STATE; /* The state machine states of a control pipe */
typedef struct OneDescriptor
{
uint8_t *Descriptor;
uint16_t Descriptor_Size;
}
ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
/* All the request process routines return a value of this type
If the return value is not SUCCESS or NOT_READY,
the software will STALL the correspond endpoint */
typedef enum _RESULT
{
USB_SUCCESS = 0, /* Process sucessfully */
USB_ERROR,
USB_UNSUPPORT,
USB_NOT_READY /* The process has not been finished, endpoint will be
NAK to further rquest */
} RESULT;
/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _ENDPOINT_INFO
{
/* When send data out of the device,
CopyData() is used to get data buffer 'Length' bytes data
if Length is 0,
CopyData() returns the total length of the data
if the request is not supported, returns 0
(NEW Feature )
if CopyData() returns -1, the calling routine should not proceed
further and will resume the SETUP process by the class device
if Length is not 0,
CopyData() returns a pointer to indicate the data location
Usb_wLength is the data remain to be sent,
Usb_wOffset is the Offset of original data
When receive data from the host,
CopyData() is used to get user data buffer which is capable
of Length bytes data to copy data from the endpoint buffer.
if Length is 0,
CopyData() returns the available data length,
if Length is not 0,
CopyData() returns user buffer address
Usb_rLength is the data remain to be received,
Usb_rPointer is the Offset of data buffer
*/
uint16_t Usb_wLength;
uint16_t Usb_wOffset;
uint16_t PacketSize;
uint8_t *(*CopyData)(uint16_t Length);
}ENDPOINT_INFO;
/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _DEVICE
{
uint8_t Total_Endpoint; /* Number of endpoints that are used */
uint8_t Total_Configuration;/* Number of configuration available */
}
DEVICE;
typedef union
{
uint16_t w;
struct BW
{
uint8_t bb1;
uint8_t bb0;
}
bw;
} uint16_t_uint8_t;
typedef struct _DEVICE_INFO
{
uint8_t USBbmRequestType; /* bmRequestType */
uint8_t USBbRequest; /* bRequest */
uint16_t_uint8_t USBwValues; /* wValue */
uint16_t_uint8_t USBwIndexs; /* wIndex */
uint16_t_uint8_t USBwLengths; /* wLength */
uint8_t ControlState; /* of type CONTROL_STATE */
uint8_t Current_Feature;
uint8_t Current_Configuration; /* Selected configuration */
uint8_t Current_Interface; /* Selected interface of current configuration */
uint8_t Current_AlternateSetting;/* Selected Alternate Setting of current
interface*/
ENDPOINT_INFO Ctrl_Info;
}DEVICE_INFO;
typedef struct _DEVICE_PROP
{
void (*Init)(void); /* Initialize the device */
void (*Reset)(void); /* Reset routine of this device */
/* Device dependent process after the status stage */
void (*Process_Status_IN)(void);
void (*Process_Status_OUT)(void);
/* Procedure of process on setup stage of a class specified request with data stage */
/* All class specified requests with data stage are processed in Class_Data_Setup
Class_Data_Setup()
responses to check all special requests and fills ENDPOINT_INFO
according to the request
If IN tokens are expected, then wLength & wOffset will be filled
with the total transferring bytes and the starting position
If OUT tokens are expected, then rLength & rOffset will be filled
with the total expected bytes and the starting position in the buffer
If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
CAUTION:
Since GET_CONFIGURATION & GET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_Data_Setup)(uint8_t RequestNo);
/* Procedure of process on setup stage of a class specified request without data stage */
/* All class specified requests without data stage are processed in Class_NoData_Setup
Class_NoData_Setup
responses to check all special requests and perform the request
CAUTION:
Since SET_CONFIGURATION & SET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_NoData_Setup)(uint8_t RequestNo);
/*Class_Get_Interface_Setting
This function is used by the file usb_core.c to test if the selected Interface
and Alternate Setting (uint8_t Interface, uint8_t AlternateSetting) are supported by
the application.
This function is writing by user. It should return "SUCCESS" if the Interface
and Alternate Setting are supported by the application or "UNSUPPORT" if they
are not supported. */
RESULT (*Class_Get_Interface_Setting)(uint8_t Interface, uint8_t AlternateSetting);
uint8_t* (*GetDeviceDescriptor)(uint16_t Length);
uint8_t* (*GetConfigDescriptor)(uint16_t Length);
uint8_t* (*GetStringDescriptor)(uint16_t Length);
uint8_t* RxEP_buffer;
uint8_t MaxPacketSize;
}DEVICE_PROP;
typedef struct _USER_STANDARD_REQUESTS
{
void (*User_GetConfiguration)(void); /* Get Configuration */
void (*User_SetConfiguration)(void); /* Set Configuration */
void (*User_GetInterface)(void); /* Get Interface */
void (*User_SetInterface)(void); /* Set Interface */
void (*User_GetStatus)(void); /* Get Status */
void (*User_ClearFeature)(void); /* Clear Feature */
void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */
void (*User_SetDeviceFeature)(void); /* Set Device Feature */
void (*User_SetDeviceAddress)(void); /* Set Device Address */
}
USER_STANDARD_REQUESTS;
/* Exported constants --------------------------------------------------------*/
#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT))
#define Usb_rLength Usb_wLength
#define Usb_rOffset Usb_wOffset
#define USBwValue USBwValues.w
#define USBwValue0 USBwValues.bw.bb0
#define USBwValue1 USBwValues.bw.bb1
#define USBwIndex USBwIndexs.w
#define USBwIndex0 USBwIndexs.bw.bb0
#define USBwIndex1 USBwIndexs.bw.bb1
#define USBwLength USBwLengths.w
#define USBwLength0 USBwLengths.bw.bb0
#define USBwLength1 USBwLengths.bw.bb1
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint8_t Setup0_Process(void);
uint8_t Post0_Process(void);
uint8_t Out0_Process(void);
uint8_t In0_Process(void);
RESULT Standard_SetEndPointFeature(void);
RESULT Standard_SetDeviceFeature(void);
uint8_t *Standard_GetConfiguration(uint16_t Length);
RESULT Standard_SetConfiguration(void);
uint8_t *Standard_GetInterface(uint16_t Length);
RESULT Standard_SetInterface(void);
uint8_t *Standard_GetDescriptorData(uint16_t Length, PONE_DESCRIPTOR pDesc);
uint8_t *Standard_GetStatus(uint16_t Length);
RESULT Standard_ClearFeature(void);
void SetDeviceAddress(uint8_t);
void NOP_Process(void);
extern const DEVICE_PROP Device_Property;
extern const USER_STANDARD_REQUESTS User_Standard_Requests;
extern const DEVICE Device_Table;
extern DEVICE_INFO Device_Info;
/* cells saving status during interrupt servicing */
extern __IO uint16_t SaveRState;
extern __IO uint16_t SaveTState;
#endif /* __USB_CORE_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,80 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_def.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Definitions related to USB Core
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEF_H
#define __USB_DEF_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _RECIPIENT_TYPE
{
DEVICE_RECIPIENT, /* Recipient device */
INTERFACE_RECIPIENT, /* Recipient interface */
ENDPOINT_RECIPIENT, /* Recipient endpoint */
OTHER_RECIPIENT
} RECIPIENT_TYPE;
typedef enum _STANDARD_REQUESTS
{
GET_STATUS = 0,
CLEAR_FEATURE,
RESERVED1,
SET_FEATURE,
RESERVED2,
SET_ADDRESS,
GET_DESCRIPTOR,
SET_DESCRIPTOR,
GET_CONFIGURATION,
SET_CONFIGURATION,
GET_INTERFACE,
SET_INTERFACE,
TOTAL_sREQUEST, /* Total number of Standard request */
SYNCH_FRAME = 12
} STANDARD_REQUESTS;
/* Definition of "USBwValue" */
typedef enum _DESCRIPTOR_TYPE
{
DEVICE_DESCRIPTOR = 1,
CONFIG_DESCRIPTOR,
STRING_DESCRIPTOR,
INTERFACE_DESCRIPTOR,
ENDPOINT_DESCRIPTOR
} DESCRIPTOR_TYPE;
/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */
typedef enum _FEATURE_SELECTOR
{
ENDPOINT_STALL,
DEVICE_REMOTE_WAKEUP
} FEATURE_SELECTOR;
/* Exported constants --------------------------------------------------------*/
/* Definition of "USBbmRequestType" */
#define REQUEST_TYPE 0x60 /* Mask to get request type */
#define STANDARD_REQUEST 0x00 /* Standard request */
#define CLASS_REQUEST 0x20 /* Class request */
#define VENDOR_REQUEST 0x40 /* Vendor request */
#define RECIPIENT 0x1F /* Mask to get recipient */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __USB_DEF_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,49 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_init.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Initialization routines & global variables
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INIT_H
#define __USB_INIT_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void USB_Init(void);
/* External variables --------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
extern uint8_t EPindex;
/* The number of current device, it is an index to the Device_Table */
/*extern uint8_t Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_INFO* pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
extern const DEVICE_PROP* pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
extern const USER_STANDARD_REQUESTS *pUser_Standard_Requests;
extern uint16_t SaveState ;
extern uint16_t wInterrupt_Mask;
#endif /* __USB_INIT_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,33 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_int.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Endpoint CTR (Low and High) interrupt's service routines
* prototypes
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INT_H
#define __USB_INT_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void CTR_LP(void);
void CTR_HP(void);
/* External variables --------------------------------------------------------*/
#endif /* __USB_INT_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,50 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_lib.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : USB library include files
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_LIB_H
#define __USB_LIB_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "usb_type.h"
#include "usb_regs.h"
#include "usb_def.h"
#include "usb_core.h"
#include "usb_init.h"
#ifndef STM32F10X_CL
#include "usb_mem.h"
#include "usb_int.h"
#endif /* STM32F10X_CL */
#include "usb_sil.h"
#ifdef STM32F10X_CL
#include "otgd_fs_cal.h"
#include "otgd_fs_pcd.h"
#include "otgd_fs_dev.h"
#include "otgd_fs_int.h"
#endif /* STM32F10X_CL */
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_LIB_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,32 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_mem.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Utility prototypes functions for memory/PMA transfers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_MEM_H
#define __USB_MEM_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes);
/* External variables --------------------------------------------------------*/
#endif /*__USB_MEM_H*/
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,670 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_regs.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Interface prototype functions to USB cell registers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REGS_H
#define __USB_REGS_H
#ifndef STM32F10X_CL
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _EP_DBUF_DIR
{
/* double buffered endpoint direction */
EP_DBUF_ERR,
EP_DBUF_OUT,
EP_DBUF_IN
}EP_DBUF_DIR;
/* endpoint buffer number */
enum EP_BUF_NUM
{
EP_NOBUF,
EP_BUF0,
EP_BUF1
};
/* Exported constants --------------------------------------------------------*/
#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */
#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */
/******************************************************************************/
/* General registers */
/******************************************************************************/
/* Control register */
#define CNTR ((__IO unsigned *)(RegBase + 0x40))
/* Interrupt status register */
#define ISTR ((__IO unsigned *)(RegBase + 0x44))
/* Frame number register */
#define FNR ((__IO unsigned *)(RegBase + 0x48))
/* Device address register */
#define DADDR ((__IO unsigned *)(RegBase + 0x4C))
/* Buffer Table address register */
#define BTABLE ((__IO unsigned *)(RegBase + 0x50))
/******************************************************************************/
/* Endpoint registers */
/******************************************************************************/
#define EP0REG ((__IO unsigned *)(RegBase)) /* endpoint 0 register address */
/* Endpoint Addresses (w/direction) */
#define EP0_OUT ((uint8_t)0x00)
#define EP0_IN ((uint8_t)0x80)
#define EP1_OUT ((uint8_t)0x01)
#define EP1_IN ((uint8_t)0x81)
#define EP2_OUT ((uint8_t)0x02)
#define EP2_IN ((uint8_t)0x82)
#define EP3_OUT ((uint8_t)0x03)
#define EP3_IN ((uint8_t)0x83)
#define EP4_OUT ((uint8_t)0x04)
#define EP4_IN ((uint8_t)0x84)
#define EP5_OUT ((uint8_t)0x05)
#define EP5_IN ((uint8_t)0x85)
#define EP6_OUT ((uint8_t)0x06)
#define EP6_IN ((uint8_t)0x86)
#define EP7_OUT ((uint8_t)0x07)
#define EP7_IN ((uint8_t)0x87)
/* endpoints enumeration */
#define ENDP0 ((uint8_t)0)
#define ENDP1 ((uint8_t)1)
#define ENDP2 ((uint8_t)2)
#define ENDP3 ((uint8_t)3)
#define ENDP4 ((uint8_t)4)
#define ENDP5 ((uint8_t)5)
#define ENDP6 ((uint8_t)6)
#define ENDP7 ((uint8_t)7)
/******************************************************************************/
/* ISTR interrupt events */
/******************************************************************************/
#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */
#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */
#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */
#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */
#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */
#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */
#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */
#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */
#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */
#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */
#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */
#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/
#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */
#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */
#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */
#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */
#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */
#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */
/******************************************************************************/
/* CNTR control register bits definitions */
/******************************************************************************/
#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */
#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */
#define CNTR_ERRM (0x2000) /* ERRor Mask */
#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */
#define CNTR_SUSPM (0x0800) /* SUSPend Mask */
#define CNTR_RESETM (0x0400) /* RESET Mask */
#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */
#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */
#define CNTR_RESUME (0x0010) /* RESUME request */
#define CNTR_FSUSP (0x0008) /* Force SUSPend */
#define CNTR_LPMODE (0x0004) /* Low-power MODE */
#define CNTR_PDWN (0x0002) /* Power DoWN */
#define CNTR_FRES (0x0001) /* Force USB RESet */
/******************************************************************************/
/* FNR Frame Number Register bit definitions */
/******************************************************************************/
#define FNR_RXDP (0x8000) /* status of D+ data line */
#define FNR_RXDM (0x4000) /* status of D- data line */
#define FNR_LCK (0x2000) /* LoCKed */
#define FNR_LSOF (0x1800) /* Lost SOF */
#define FNR_FN (0x07FF) /* Frame Number */
/******************************************************************************/
/* DADDR Device ADDRess bit definitions */
/******************************************************************************/
#define DADDR_EF (0x80)
#define DADDR_ADD (0x7F)
/******************************************************************************/
/* Endpoint register */
/******************************************************************************/
/* bit positions */
#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */
#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */
#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */
#define EP_SETUP (0x0800) /* EndPoint SETUP */
#define EP_T_FIELD (0x0600) /* EndPoint TYPE */
#define EP_KIND (0x0100) /* EndPoint KIND */
#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */
#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */
#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */
#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */
/* EndPoint REGister MASK (no toggle fields) */
#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD)
/* EP_TYPE[1:0] EndPoint TYPE */
#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */
#define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK)
/* EP_KIND EndPoint KIND */
#define EPKIND_MASK (~EP_KIND & EPREG_MASK)
/* STAT_TX[1:0] STATus for TX transfer */
#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */
#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */
#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */
#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */
#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */
#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */
#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK)
/* STAT_RX[1:0] STATus for RX transfer */
#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */
#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */
#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */
#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */
#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK)
/* Exported macro ------------------------------------------------------------*/
/* SetCNTR */
#define _SetCNTR(wRegValue) (*CNTR = (uint16_t)wRegValue)
/* SetISTR */
#define _SetISTR(wRegValue) (*ISTR = (uint16_t)wRegValue)
/* SetDADDR */
#define _SetDADDR(wRegValue) (*DADDR = (uint16_t)wRegValue)
/* SetBTABLE */
#define _SetBTABLE(wRegValue)(*BTABLE = (uint16_t)(wRegValue & 0xFFF8))
/* GetCNTR */
#define _GetCNTR() ((uint16_t) *CNTR)
/* GetISTR */
#define _GetISTR() ((uint16_t) *ISTR)
/* GetFNR */
#define _GetFNR() ((uint16_t) *FNR)
/* GetDADDR */
#define _GetDADDR() ((uint16_t) *DADDR)
/* GetBTABLE */
#define _GetBTABLE() ((uint16_t) *BTABLE)
/* SetENDPOINT */
#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \
(uint16_t)wRegValue)
/* GetENDPOINT */
#define _GetENDPOINT(bEpNum) ((uint16_t)(*(EP0REG + bEpNum)))
/*******************************************************************************
* Macro Name : SetEPType
* Description : sets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* wType
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\
((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType )))
/*******************************************************************************
* Macro Name : GetEPType
* Description : gets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Type
*******************************************************************************/
#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD)
/*******************************************************************************
* Macro Name : SetEPTxStatus
* Description : sets the status for tx transfer (bits STAT_TX[1:0]).
* Input : bEpNum: Endpoint Number.
* wState: new state
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxStatus(bEpNum,wState) {\
register uint16_t _wRegVal; \
_wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX)); \
} /* _SetEPTxStatus */
/*******************************************************************************
* Macro Name : SetEPRxStatus
* Description : sets the status for rx transfer (bits STAT_TX[1:0])
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxStatus(bEpNum,wState) {\
register uint16_t _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
_SetENDPOINT(bEpNum, (_wRegVal | EP_CTR_RX|EP_CTR_TX)); \
} /* _SetEPRxStatus */
/*******************************************************************************
* Macro Name : SetEPRxTxStatus
* Description : sets the status for rx & tx (bits STAT_TX[1:0] & STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* wStaterx: new state.
* wStatetx: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxTxStatus(bEpNum,wStaterx,wStatetx) {\
register uint32_t _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & (EPRX_DTOGMASK |EPTX_STAT) ;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wStaterx)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wStaterx)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wStatetx)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wStatetx)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, _wRegVal | EP_CTR_RX|EP_CTR_TX); \
} /* _SetEPRxTxStatus */
/*******************************************************************************
* Macro Name : GetEPTxStatus / GetEPRxStatus
* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0]
* /STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : status .
*******************************************************************************/
#define _GetEPTxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPTX_STAT)
#define _GetEPRxStatus(bEpNum) ((uint16_t)_GetENDPOINT(bEpNum) & EPRX_STAT)
/*******************************************************************************
* Macro Name : SetEPTxValid / SetEPRxValid
* Description : sets directly the VALID tx/rx-status into the enpoint register
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID))
#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID))
/*******************************************************************************
* Macro Name : GetTxStallStatus / GetRxStallStatus.
* Description : checks stall condition in an endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : TRUE = endpoint in stall condition.
*******************************************************************************/
#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \
== EP_TX_STALL)
#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \
== EP_RX_STALL)
/*******************************************************************************
* Macro Name : SetEP_KIND / ClearEP_KIND.
* Description : set & clear EP_KIND bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \
(EP_CTR_RX|EP_CTR_TX|((_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK))))
#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \
(EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPKIND_MASK))))
/*******************************************************************************
* Macro Name : Set_Status_Out / Clear_Status_Out.
* Description : Sets/clears directly STATUS_OUT bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum)
#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum)
/*******************************************************************************
* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff.
* Description : Sets/clears directly EP_KIND bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum)
#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum)
/*******************************************************************************
* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX.
* Description : Clears bit CTR_RX / CTR_TX in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK))
#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK))
/*******************************************************************************
* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX .
* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_CTR_RX|EP_CTR_TX|EP_DTOG_RX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_CTR_RX|EP_CTR_TX|EP_DTOG_TX | (_GetENDPOINT(bEpNum) & EPREG_MASK)))
/*******************************************************************************
* Macro Name : ClearDTOG_RX / ClearDTOG_TX.
* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\
_ToggleDTOG_RX(bEpNum)
#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\
_ToggleDTOG_TX(bEpNum)
/*******************************************************************************
* Macro Name : SetEPAddress.
* Description : Sets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* bAddr: Address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\
EP_CTR_RX|EP_CTR_TX|(_GetENDPOINT(bEpNum) & EPREG_MASK) | bAddr)
/*******************************************************************************
* Macro Name : GetEPAddress.
* Description : Gets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPAddress(bEpNum) ((uint8_t)(_GetENDPOINT(bEpNum) & EPADDR_FIELD))
#define _pEPTxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr))
#define _pEPTxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr))
#define _pEPRxAddr(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr))
#define _pEPRxCount(bEpNum) ((uint32_t *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr))
/*******************************************************************************
* Macro Name : SetEPTxAddr / SetEPRxAddr.
* Description : sets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* wAddr: address to be set (must be word aligned).
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1))
/*******************************************************************************
* Macro Name : GetEPTxAddr / GetEPRxAddr.
* Description : Gets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : address of the buffer.
*******************************************************************************/
#define _GetEPTxAddr(bEpNum) ((uint16_t)*_pEPTxAddr(bEpNum))
#define _GetEPRxAddr(bEpNum) ((uint16_t)*_pEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPCountRxReg.
* Description : Sets counter of rx buffer with no. of blocks.
* Input : pdwReg: pointer to counter.
* wCount: Counter.
* Output : None.
* Return : None.
*******************************************************************************/
#define _BlocksOf32(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 5;\
if((wCount & 0x1f) == 0)\
wNBlocks--;\
*pdwReg = (uint32_t)((wNBlocks << 10) | 0x8000);\
}/* _BlocksOf32 */
#define _BlocksOf2(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 1;\
if((wCount & 0x1) != 0)\
wNBlocks++;\
*pdwReg = (uint32_t)(wNBlocks << 10);\
}/* _BlocksOf2 */
#define _SetEPCountRxReg(dwReg,wCount) {\
uint16_t wNBlocks;\
if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\
else {_BlocksOf2(dwReg,wCount,wNBlocks);}\
}/* _SetEPCountRxReg */
#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\
uint32_t *pdwReg = _pEPTxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : SetEPTxCount / SetEPRxCount.
* Description : sets counter for the tx/rx buffer.
* Input : bEpNum: endpoint number.
* wCount: Counter value.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount)
#define _SetEPRxCount(bEpNum,wCount) {\
uint32_t *pdwReg = _pEPRxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : GetEPTxCount / GetEPRxCount.
* Description : gets counter of the tx buffer.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : Counter value.
*******************************************************************************/
#define _GetEPTxCount(bEpNum)((uint16_t)(*_pEPTxCount(bEpNum)) & 0x3ff)
#define _GetEPRxCount(bEpNum)((uint16_t)(*_pEPRxCount(bEpNum)) & 0x3ff)
/*******************************************************************************
* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr.
* Description : Sets buffer 0/1 address in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);}
#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);}
/*******************************************************************************
* Macro Name : SetEPDblBuffAddr.
* Description : Sets addresses in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* : wBuf1Addr = buffer 1 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\
} /* _SetEPDblBuffAddr */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum))
#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : bDir: endpoint dir EP_DBUF_OUT = OUT
* EP_DBUF_IN = IN
* : wCount: Counter value
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxDblBuf0Count(bEpNum,wCount);} \
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */ \
*_pEPTxCount(bEpNum) = (uint32_t)wCount; \
} /* SetEPDblBuf0Count*/
#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxCount(bEpNum,wCount);}\
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */\
*_pEPRxCount(bEpNum) = (uint32_t)wCount; \
} /* SetEPDblBuf1Count */
#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\
_SetEPDblBuf0Count(bEpNum, bDir, wCount); \
_SetEPDblBuf1Count(bEpNum, bDir, wCount); \
} /* _SetEPDblBuffCount */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count.
* Description : Gets buffer 0/1 rx/tx counter for double buffering.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum))
#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum))
/* External variables --------------------------------------------------------*/
extern __IO uint16_t wIstr; /* ISTR register last read value */
/* Exported functions ------------------------------------------------------- */
void SetCNTR(uint16_t /*wRegValue*/);
void SetISTR(uint16_t /*wRegValue*/);
void SetDADDR(uint16_t /*wRegValue*/);
void SetBTABLE(uint16_t /*wRegValue*/);
uint16_t GetCNTR(void);
uint16_t GetISTR(void);
uint16_t GetFNR(void);
uint16_t GetDADDR(void);
uint16_t GetBTABLE(void);
void SetENDPOINT(uint8_t /*bEpNum*/, uint16_t /*wRegValue*/);
uint16_t GetENDPOINT(uint8_t /*bEpNum*/);
void SetEPType(uint8_t /*bEpNum*/, uint16_t /*wType*/);
uint16_t GetEPType(uint8_t /*bEpNum*/);
void SetEPTxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
void SetEPRxStatus(uint8_t /*bEpNum*/, uint16_t /*wState*/);
void SetDouBleBuffEPStall(uint8_t /*bEpNum*/, uint8_t bDir);
uint16_t GetEPTxStatus(uint8_t /*bEpNum*/);
uint16_t GetEPRxStatus(uint8_t /*bEpNum*/);
void SetEPTxValid(uint8_t /*bEpNum*/);
void SetEPRxValid(uint8_t /*bEpNum*/);
uint16_t GetTxStallStatus(uint8_t /*bEpNum*/);
uint16_t GetRxStallStatus(uint8_t /*bEpNum*/);
void SetEP_KIND(uint8_t /*bEpNum*/);
void ClearEP_KIND(uint8_t /*bEpNum*/);
void Set_Status_Out(uint8_t /*bEpNum*/);
void Clear_Status_Out(uint8_t /*bEpNum*/);
void SetEPDoubleBuff(uint8_t /*bEpNum*/);
void ClearEPDoubleBuff(uint8_t /*bEpNum*/);
void ClearEP_CTR_RX(uint8_t /*bEpNum*/);
void ClearEP_CTR_TX(uint8_t /*bEpNum*/);
void ToggleDTOG_RX(uint8_t /*bEpNum*/);
void ToggleDTOG_TX(uint8_t /*bEpNum*/);
void ClearDTOG_RX(uint8_t /*bEpNum*/);
void ClearDTOG_TX(uint8_t /*bEpNum*/);
void SetEPAddress(uint8_t /*bEpNum*/, uint8_t /*bAddr*/);
uint8_t GetEPAddress(uint8_t /*bEpNum*/);
void SetEPTxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
void SetEPRxAddr(uint8_t /*bEpNum*/, uint16_t /*wAddr*/);
uint16_t GetEPTxAddr(uint8_t /*bEpNum*/);
uint16_t GetEPRxAddr(uint8_t /*bEpNum*/);
void SetEPCountRxReg(uint32_t * /*pdwReg*/, uint16_t /*wCount*/);
void SetEPTxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
void SetEPRxCount(uint8_t /*bEpNum*/, uint16_t /*wCount*/);
uint16_t GetEPTxCount(uint8_t /*bEpNum*/);
uint16_t GetEPRxCount(uint8_t /*bEpNum*/);
void SetEPDblBuf0Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/);
void SetEPDblBuf1Addr(uint8_t /*bEpNum*/, uint16_t /*wBuf1Addr*/);
void SetEPDblBuffAddr(uint8_t /*bEpNum*/, uint16_t /*wBuf0Addr*/, uint16_t /*wBuf1Addr*/);
uint16_t GetEPDblBuf0Addr(uint8_t /*bEpNum*/);
uint16_t GetEPDblBuf1Addr(uint8_t /*bEpNum*/);
void SetEPDblBuffCount(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
void SetEPDblBuf0Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
void SetEPDblBuf1Count(uint8_t /*bEpNum*/, uint8_t /*bDir*/, uint16_t /*wCount*/);
uint16_t GetEPDblBuf0Count(uint8_t /*bEpNum*/);
uint16_t GetEPDblBuf1Count(uint8_t /*bEpNum*/);
EP_DBUF_DIR GetEPDblBufDir(uint8_t /*bEpNum*/);
void FreeUserBuffer(uint8_t bEpNum/*bEpNum*/, uint8_t bDir);
uint16_t ToWord(uint8_t, uint8_t);
uint16_t ByteSwap(uint16_t);
#endif /* STM32F10X_CL */
#endif /* __USB_REGS_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,34 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_sil.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Simplified Interface Layer function prototypes.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_SIL_H
#define __USB_SIL_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
uint32_t USB_SIL_Init(void);
uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize);
uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer);
/* External variables --------------------------------------------------------*/
#endif /* __USB_SIL_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,74 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_type.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Type definitions used by the USB Library
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_TYPE_H
#define __USB_TYPE_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef __STM32F10x_H
typedef signed long s32;
typedef signed short s16;
typedef signed char s8;
typedef volatile signed long vs32;
typedef volatile signed short vs16;
typedef volatile signed char vs8;
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long const uc32; /* Read Only */
typedef unsigned short const uc16; /* Read Only */
typedef unsigned char const uc8; /* Read Only */
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
typedef volatile unsigned long const vuc32; /* Read Only */
typedef volatile unsigned short const vuc16; /* Read Only */
typedef volatile unsigned char const vuc8; /* Read Only */
typedef enum
{
FALSE = 0, TRUE = !FALSE
}
bool;
typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus;
typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
#endif
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_TYPE_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@@ -1,386 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : otgd_fs_dev.c
* Author : STMicroelectronics
* Version : V3.1.1
* Date : 04/07/2010
* Description : High Layer device mode interface and wrapping layer.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifdef STM32F10X_CL
/* Includes ------------------------------------------------------------------*/
#include "otgd_fs_dev.h"
#include "usb_regs.h"
#include "otgd_fs_cal.h"
#include "otgd_fs_pcd.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : OTG_DEV_Init
* Description : Initialize the OTG Device IP and EP0.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void OTG_DEV_Init(void)
{
EP_DESCRIPTOR ep_descriptor;
USB_OTG_EP *ep;
/* Set the OTG_USB base registers address */
OTGD_FS_SetAddress(USB_OTG_FS1_BASE_ADDR);
/* Disable all global interrupts */
OTGD_FS_DisableGlobalInt();
/*Init the Core (common init.) */
OTGD_FS_CoreInit();
/* Init Device */
OTGD_FS_CoreInitDev();
/* Init internal driver structure */
OTGD_FS_PCD_Init();
/* Configure and open the IN control EP0 */
ep_descriptor.bEndpointAddress = 0x80;
ep_descriptor.wMaxPacketSize = 64;
ep_descriptor.bmAttributes = USB_ENDPOINT_XFER_CONTROL;
OTGD_FS_PCD_EP_Open(&ep_descriptor);
/* Configure and open the OUT control EP0 */
ep_descriptor.bEndpointAddress = 0x00;
OTGD_FS_PCD_EP_Open(&ep_descriptor);
ep = OTGD_FS_PCD_GetOutEP(0);
OTGD_FS_EPStartXfer(ep);
/* Enable EP0 to start receiving setup packets */
OTGD_FS_PCD_EP0_OutStart();
/* Enable USB Global interrupt */
OTGD_FS_EnableGlobalInt();
}
/*******************************************************************************
* Function Name : OTG_DEV_EP_Init
* Description : Initialize the selected endpoint parameters
* Input : - bEpAdd: address of the endpoint (epnum|epdir)
* expample: EP1 OUT -> 0x01 and EP1 IN 0x81.
* - bEpType: OTG_DEV_EP_TYPE_CONTROL, OTG_DEV_EP_TYPE_ISOC,
* OTG_DEV_EP_TYPE_BULK, OTG_DEV_EP_TYPE_INT
* - wEpMaxPackSize: The EP max packet size.
* Output : None.
* Return : Status: New status to be set for the endpoint:
*******************************************************************************/
void OTG_DEV_EP_Init(uint8_t bEpAdd, uint8_t bEpType, uint16_t wEpMaxPackSize)
{
EP_DESCRIPTOR ep_descriptor;
USB_OTG_EP *ep;
/* Set the EP parameters in a structure */
ep_descriptor.bEndpointAddress = bEpAdd;
ep_descriptor.bmAttributes = bEpType;
ep_descriptor.wMaxPacketSize = wEpMaxPackSize;
OTGD_FS_PCD_EP_Flush(bEpAdd);
/* Open the EP with entered parameters */
OTGD_FS_PCD_EP_Open(&ep_descriptor);
/* Activate the EP if it is an OUT EP */
if ((bEpAdd & 0x80) == 0)
{
ep = OTGD_FS_PCD_GetOutEP(bEpAdd & 0x7F);
OTGD_FS_EPStartXfer(ep);
}
else
{
ep = OTGD_FS_PCD_GetInEP(bEpAdd & 0x7F);
ep->even_odd_frame = 0;
OTG_DEV_SetEPTxStatus(bEpAdd, DEV_EP_TX_NAK);
}
}
/*******************************************************************************
* Function Name : OTG_DEV_GetEPTxStatus
* Description : Set the related endpoint status.
* Input : Number of the endpoint.
* Output : None.
* Return : Status: New status to be set for the endpoint:
*******************************************************************************/
uint32_t OTG_DEV_GetEPTxStatus(uint8_t bEpnum)
{
USB_OTG_EP *ep;
uint32_t status = 0;
ep = OTGD_FS_PCD_GetInEP(bEpnum & 0x7F);
status = OTGD_FS_Dev_GetEPStatus(ep);
return status;
}
/*******************************************************************************
* Function Name : OTG_DEV_GetEPRxStatus
* Description : returns the related endpoint status.
* Input : Number of the endpoint.
* Output : None.
* Return : Status: New status to be set for the endpoint:
*******************************************************************************/
uint32_t OTG_DEV_GetEPRxStatus(uint8_t bEpnum)
{
USB_OTG_EP *ep;
uint32_t status = 0;
ep = OTGD_FS_PCD_GetOutEP(bEpnum & 0x7F);
status = OTGD_FS_Dev_GetEPStatus(ep);
return status;
}
/*******************************************************************************
* Function Name : OTG_DEV_SetEPTxStatus
* Description : Sets the related endpoint status.
* Input : - bEpnum: Number of the endpoint.
* - Status: New status to be set for the endpoint. It can be
* DEV_EP_TX_VALID, DEV_EP_TX_STALL, DEV_EP_TX_NAK or
* DEV_EP_TX_DISABLE.
* Output : None.
* Return : None.
*******************************************************************************/
void OTG_DEV_SetEPTxStatus(uint8_t bEpnum, uint32_t Status)
{
USB_OTG_EP *ep;
ep = OTGD_FS_PCD_GetInEP(bEpnum & 0x7F);
if ((bEpnum == 0x80) && (Status == DEV_EP_TX_STALL))
{
ep->is_in = 1;
}
OTGD_FS_Dev_SetEPStatus(ep, Status);
}
/*******************************************************************************
* Function Name : OTG_DEV_SetEPRxStatus
* Description : Sets the related endpoint status.
* Input : - bEpnum: Number of the endpoint.
* - Status: New status to be set for the endpoint. It can be
* DEV_EP_RX_VALID, DEV_EP_RX_STALL, DEV_EP_RX_NAK or
* DEV_EP_RX_DISABLE.
* Output : None.
* Return : None.
*******************************************************************************/
void OTG_DEV_SetEPRxStatus(uint8_t bEpnum, uint32_t Status)
{
USB_OTG_EP *ep;
ep = OTGD_FS_PCD_GetOutEP(bEpnum & 0x7F);
OTGD_FS_Dev_SetEPStatus(ep, Status);
}
/*******************************************************************************
* Function Name : USB_DevDisconnect
* Description : Disconnect the Pullup resist.
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void USB_DevDisconnect(void)
{
OTGD_FS_PCD_DevDisconnect();
}
/*******************************************************************************
* Function Name : USB_DevConnect
* Description : Disconnect the .
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void USB_DevConnect(void)
{
OTGD_FS_PCD_DevConnect();
}
/*-*-*-*-*-*-*-*-*-* Replace the usb_regs.h defines -*-*-*-*-*-*-*-*-*-*-*-*-*/
/*******************************************************************************
* Function Name : SetEPTxStatus
* Description : Set the status of Tx endpoint.
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxStatus(uint8_t bEpNum, uint16_t wState)
{
_SetEPTxStatus(bEpNum, wState);
}
/*******************************************************************************
* Function Name : SetEPRxStatus
* Description : Set the status of Rx endpoint.
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxStatus(uint8_t bEpNum, uint16_t wState)
{
_SetEPRxStatus(bEpNum, wState);
}
/*******************************************************************************
* Function Name : GetEPTxStatus
* Description : Returns the endpoint Tx status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint TX Status
*******************************************************************************/
uint16_t GetEPTxStatus(uint8_t bEpNum)
{
return(_GetEPTxStatus(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPRxStatus
* Description : Returns the endpoint Rx status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint RX Status
*******************************************************************************/
uint16_t GetEPRxStatus(uint8_t bEpNum)
{
return(_GetEPRxStatus(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxValid
* Description : Valid the endpoint Tx Status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxValid(uint8_t bEpNum)
{
_SetEPTxStatus(bEpNum, EP_TX_VALID);
}
/*******************************************************************************
* Function Name : SetEPRxValid
* Description : Valid the endpoint Rx Status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxValid(uint8_t bEpNum)
{
_SetEPRxStatus(bEpNum, EP_RX_VALID);
}
/*******************************************************************************
* Function Name : GetTxStallStatus
* Description : Returns the Stall status of the Tx endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Tx Stall status.
*******************************************************************************/
uint16_t GetTxStallStatus(uint8_t bEpNum)
{
return(_GetTxStallStatus(bEpNum));
}
/*******************************************************************************
* Function Name : GetRxStallStatus
* Description : Returns the Stall status of the Rx endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx Stall status.
*******************************************************************************/
uint16_t GetRxStallStatus(uint8_t bEpNum)
{
return(_GetRxStallStatus(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxCount.
* Description : Set the Tx count.
* Input : bEpNum: Endpoint Number.
* wCount: new count value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxCount(uint8_t bEpNum, uint16_t wCount)
{
}
/*******************************************************************************
* Function Name : SetEPRxCount
* Description : Set the Rx count.
* Input : bEpNum: Endpoint Number.
* wCount: the new count value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxCount(uint8_t bEpNum, uint16_t wCount)
{
}
/*******************************************************************************
* Function Name : ToWord
* Description : merge two byte in a word.
* Input : bh: byte high, bl: bytes low.
* Output : None.
* Return : resulted word.
*******************************************************************************/
uint16_t ToWord(uint8_t bh, uint8_t bl)
{
uint16_t wRet = 0;
wRet = (uint16_t)bl | ((uint16_t)bh << 8);
return(wRet);
}
/*******************************************************************************
* Function Name : ByteSwap
* Description : Swap two byte in a word.
* Input : wSwW: word to Swap.
* Output : None.
* Return : resulted word.
*******************************************************************************/
uint16_t ByteSwap(uint16_t wSwW)
{
uint8_t bTemp = 0;
uint16_t wRet = 0;
bTemp = (uint8_t)(wSwW & 0xff);
wRet = (wSwW >> 8) | ((uint16_t)bTemp << 8);
return(wRet);
}
#endif /* STM32F10X_CL */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,874 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : otgd_fs_int.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Endpoint interrupt's service routines.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifdef STM32F10X_CL
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "usb_type.h"
#include "otgd_fs_int.h"
#include "usb_lib.h"
#include "usb_istr.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Max size of the received OUT Non periodic packet */
#define MAX_OUT_PKT_SIZE 160
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t USBD_Data_Buffer [MAX_OUT_PKT_SIZE];
__IO uint8_t IsocBuff [(ISOC_BUFFER_SZE * NUM_SUB_BUFFERS)];
__IO uint32_t IsocBufferIdx = 0;
extern USB_OTG_CORE_REGS core_regs;
__IO uint16_t SaveRState;
__IO uint16_t SaveTState;
/* Extern variables ----------------------------------------------------------*/
extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */
extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */
/* Private function prototypes -----------------------------------------------*/
static uint32_t OTGD_FS_PCD_ReadDevInEP( USB_OTG_EP *ep);
static enum usb_device_speed OTGD_FS_PCD_GetDeviceSpeed(void);
static uint32_t OTGD_FS_PCD_WriteEmptyTxFifo(uint32_t epnum);
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : OTGD_FS_Handle_ModeMismatch_ISR
* Description : Handles the Mode Mismatch error interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_ModeMismatch_ISR(void)
{
USB_OTG_int_sts_data gintsts;
gintsts.d32 = 0 ;
INTR_MODEMISMATCH_Callback();
/* Clear interrupt */
gintsts.b.modemismatch = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_Sof_ISR
* Description : Handles the Start Of Frame detected interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_Sof_ISR(void)
{
USB_OTG_int_sts_data int_sts ;
int_sts.d32 = 0;
/* Call user function */
INTR_SOFINTR_Callback();
/* Clear interrupt */
int_sts.b.sofintr = 1;
WRITE_REG32 (&core_regs.common_regs->int_sts, int_sts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_RxStatusQueueLevel_ISR
* Description : Handles the Rx Status Queue Level Interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_RxStatusQueueLevel_ISR(void)
{
USB_OTG_int_msk_data int_mask;
USB_OTG_dev_rx_sts_data status;
USB_OTG_EP *ep;
int_mask.d32 = 0;
status.d32 = 0;
/* Disable the Rx Status Queue Level interrupt */
int_mask.b.rxstsqlvl = 1;
MODIFY_REG32( &core_regs.common_regs->int_msk, int_mask.d32, 0);
/* Get the Status from the top of the FIFO */
status.d32 = READ_REG32( &core_regs.common_regs->rx_stsp );
/* Get the related endpoint structure */
ep = OTGD_FS_PCD_GetOutEP(status.b.epnum);
switch (status.b.pktsts)
{
case STS_GOUT_NAK:
break;
case STS_DATA_UPDT:
if (status.b.bcnt)
{
if (ep->type == EP_TYPE_ISOC)
{
/* Call user function */
INTR_RXSTSQLVL_ISODU_Callback();
/* Copy the received buffer to the RAM */
OTGD_FS_ReadPacket((uint8_t*)(IsocBuff + (ISOC_BUFFER_SZE * IsocBufferIdx)), status.b.bcnt);
ep->xfer_buff = (uint8_t*)(IsocBuff + (ISOC_BUFFER_SZE * IsocBufferIdx));
/* Check if the end of the global buffer has been reached */
if (IsocBufferIdx == (NUM_SUB_BUFFERS - 1))
{
/* Reset the buffer index */
IsocBufferIdx = 0;
}
else
{
/* Increment the buffer index */
IsocBufferIdx ++;
}
}
else
{
/* Copy the received buffer to the RAM */
OTGD_FS_ReadPacket(USBD_Data_Buffer, status.b.bcnt);
ep->xfer_buff = USBD_Data_Buffer;
}
/* Update the endpoint structure */
ep->xfer_len = status.b.bcnt;
ep->xfer_count += status.b.bcnt;
}
break;
case STS_XFER_COMP:
break;
case STS_SETUP_COMP:
break;
case STS_SETUP_UPDT:
/* Copy the setup packet received in Fifo into the setup buffer in RAM */
OTGD_FS_ReadPacket(USBD_Data_Buffer, 8);
ep->xfer_buff = USBD_Data_Buffer;
ep->xfer_count += status.b.bcnt;
ep->xfer_len = status.b.bcnt;
break;
default:
break;
}
/* Call the user function */
INTR_RXSTSQLVL_Callback();
/* Enable the Rx Status Queue Level interrupt */
MODIFY_REG32( &core_regs.common_regs->int_msk, 0, int_mask.d32);
/* Clear interrupt: this is a read only bit, it cannot be cleared by register
access */
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_NPTxFE_ISR
* Description : Handles the Non Periodic Tx FIFO Empty interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_NPTxFE_ISR(void )
{
USB_OTG_int_msk_data gintmsk;
gintmsk.d32 = 0;
/* Call the user function */
INTR_NPTXFEMPTY_Callback();
gintmsk.b.nptxfempty = 1;
MODIFY_REG32(&core_regs.common_regs->int_msk, gintmsk.d32, 0 );
/* Clear interrupt: This bit is a read only bit, cannot be cleared
by register access */
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_GInNakEff_ISR
* Description : Handles the Global IN Endpoints NAK Effective interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_GInNakEff_ISR(void)
{
/* Call user function */
INTR_GINNAKEFF_Callback();
/* Clear interrupt: This is a read only bit, it cannot be cleared by register
access */
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_GOutNakEff_ISR
* Description : Handles the Global OUT Endpoints NAK Effective interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_GOutNakEff_ISR(void)
{
/* Call user function */
INTR_GOUTNAKEFF_Callback();
/* Clear interrupt: This is a read only bit, it cannot be cleared by register
access */
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_EarlySuspend_ISR
* Description : Handles the Early Suspend detected interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_EarlySuspend_ISR(void )
{
USB_OTG_int_sts_data gintsts;
USB_OTG_int_msk_data gintmsk;
gintsts.d32 = 0;
gintmsk.d32 = 0;
/* Call user function */
INTR_ERLYSUSPEND_Callback();
gintmsk.b.erlysuspend = 1;
MODIFY_REG32(&core_regs.common_regs->int_msk, gintmsk.d32, 0 );
/* Clear interrupt */
gintsts.b.erlysuspend = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_USBSuspend_ISR
* Description : Handles the Suspend condition detected interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_USBSuspend_ISR(void)
{
USB_OTG_int_sts_data gintsts;
gintsts.d32 = 0;
/* Call user function */
INTR_USBSUSPEND_Callback();
/* Clear interrupt */
gintsts.b.usbsuspend = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_UsbReset_ISR
* Description : This interrupt occurs when a USB Reset is detected.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_UsbReset_ISR(void)
{
USB_OTG_dev_all_int_data daintmsk;
USB_OTG_dev_out_ep_msk_data doepmsk;
USB_OTG_dev_in_ep_msk_data diepmsk;
USB_OTG_dev_cfg_data dcfg;
USB_OTG_dev_ctl_data dctl;
USB_OTG_int_sts_data gintsts;
daintmsk.d32 = 0;
doepmsk.d32 = 0;
diepmsk.d32 = 0;
dcfg.d32 =0;
dctl.d32 = 0;
gintsts.d32 = 0;
/* Clear the Remote Wakeup Signalling */
dctl.b.rmtwkupsig = 1;
MODIFY_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32, 0 );
/* Flush the NP Tx FIFO */
OTGD_FS_FlushTxFifo( 0 );
daintmsk.b.inep0 = 1;
daintmsk.b.outep0 = 1;
WRITE_REG32( &core_regs.dev_regs->dev_all_int_msk, daintmsk.d32 );
doepmsk.b.setup = 1;
doepmsk.b.xfercompl = 1;
doepmsk.b.ahberr = 1;
doepmsk.b.epdisabled = 1;
WRITE_REG32( &core_regs.dev_regs->dev_out_ep_msk, doepmsk.d32 );
diepmsk.b.xfercompl = 1;
diepmsk.b.timeout = 1;
diepmsk.b.epdisabled = 1;
diepmsk.b.ahberr = 1;
diepmsk.b.intknepmis = 1;
WRITE_REG32( &core_regs.dev_regs->dev_in_ep_msk, diepmsk.d32 );
/* Reset Device Address */
dcfg.d32 = READ_REG32( &core_regs.dev_regs->dev_cfg);
dcfg.b.devaddr = 0;
WRITE_REG32( &core_regs.dev_regs->dev_cfg, dcfg.d32);
/* setup EP0 to receive SETUP packets */
OTGD_FS_PCD_EP0_OutStart();
/* Clear interrupt */
gintsts.d32 = 0;
gintsts.b.usbreset = 1;
WRITE_REG32 (&core_regs.common_regs->int_sts, gintsts.d32);
/* Call the user reset function */
OTGD_FS_DEVICE_RESET;
/* Call user function */
INTR_USBRESET_Callback();
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_EnumDone_ISR
* Description : Reads the device status register and set the device speed
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_EnumDone_ISR(void)
{
USB_OTG_int_sts_data gintsts;
USB_OTG_usb_cfg_data gusbcfg;
gintsts.d32 = 0;
gusbcfg.d32 = 0;
OTGD_FS_EP0Activate();
/* Set USB turnaround time based on device speed and PHY interface. */
gusbcfg.d32 = READ_REG32(&core_regs.common_regs->usb_cfg);
/* Full or low speed */
if ( OTGD_FS_PCD_GetDeviceSpeed() == USB_SPEED_FULL)
{
gusbcfg.b.usbtrdtim = 9;
}
WRITE_REG32(&core_regs.common_regs->usb_cfg, gusbcfg.d32);
/* Call user function */
INTR_ENUMDONE_Callback();
/* Clear interrupt */
gintsts.b.enumdone = 1;
WRITE_REG32( &core_regs.common_regs->int_sts, gintsts.d32 );
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_IsoOutDrop_ISR
* Description : Handles the Isochrounous Out packet Dropped interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_IsoOutDrop_ISR(void)
{
USB_OTG_int_sts_data gintsts;
gintsts.d32 = 0;
/* Call user function */
INTR_ISOOUTDROP_Callback();
/* Clear interrupt */
gintsts.b.isooutdrop = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_EOPF_ISR
* Description : Handles the Expexted End Of Periodic Frame interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_EOPF_ISR(void )
{
USB_OTG_int_sts_data gintsts;
USB_OTG_int_msk_data gintmsk;
gintsts.d32 = 0;
gintmsk.d32 = 0;
gintmsk.b.eopframe = 1;
MODIFY_REG32(&core_regs.common_regs->int_msk, gintmsk.d32, 0 );
/* Call user function */
INTR_EOPFRAME_Callback();
/* Clear interrupt */
gintsts.b.eopframe = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_EPMismatch_ISR
* Description : Handles the Endpoint Mismatch error interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_EPMismatch_ISR(void)
{
USB_OTG_int_sts_data gintsts;
gintsts.d32 = 0;
/* Call user function */
INTR_EPMISMATCH_Callback();
/* Clear interrupt */
gintsts.b.epmismatch = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_InEP_ISR
* Description : Handles all IN endpoints interrupts.
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_InEP_ISR(void)
{
USB_OTG_dev_in_ep_int_data diepint;
uint32_t ep_intr = 0;
uint32_t epnum = 0;
USB_OTG_EP *ep;
uint32_t fifoemptymsk = 0;
diepint.d32 = 0;
ep_intr = OTGD_FS_ReadDevAllInEPItr();
while ( ep_intr )
{
if (ep_intr&0x1) /* In ITR */
{
ep = OTGD_FS_PCD_GetInEP(epnum);
diepint.d32 = OTGD_FS_PCD_ReadDevInEP(ep); /* Get In ITR status */
if ( diepint.b.xfercompl )
{
fifoemptymsk = 0x1 << ep->num;
MODIFY_REG32(&core_regs.dev_regs->dev_fifo_empty_msk, fifoemptymsk, 0);
/* Clear the Interrupt flag */
CLEAR_IN_EP_INTR(epnum, xfercompl);
if (epnum == 0)
{
/* Call the core IN process for EP0 */
In0_Process();
/* before terminate set Tx & Rx status */
OTG_DEV_SetEPRxStatus(epnum, SaveRState);
OTG_DEV_SetEPTxStatus(epnum, SaveTState);
}
else
{
OTG_DEV_SetEPTxStatus((epnum | 0x80 ), DEV_EP_TX_NAK);
(*pEpInt_IN[epnum -1])();
/* Toggle Endpoint frame ID */
if (ep->even_odd_frame == 0)
ep->even_odd_frame = 1;
else
ep->even_odd_frame = 0;
}
}
if ( diepint.b.ahberr )
{
CLEAR_IN_EP_INTR(epnum, ahberr);
}
if ( diepint.b.timeout )
{
CLEAR_IN_EP_INTR(epnum, timeout);
}
if (diepint.b.intktxfemp)
{
CLEAR_IN_EP_INTR(epnum, intktxfemp);
}
if (diepint.b.intknepmis)
{
CLEAR_IN_EP_INTR(epnum, intknepmis);
}
if (diepint.b.inepnakeff)
{
CLEAR_IN_EP_INTR(epnum, inepnakeff);
}
if (diepint.b.emptyintr)
{
if ((epnum == 0) || (OTG_DEV_GetEPTxStatus(epnum) == DEV_EP_TX_VALID))
{
OTGD_FS_PCD_WriteEmptyTxFifo(epnum);
}
CLEAR_IN_EP_INTR(epnum, emptyintr);
}
if ( diepint.b.epdisabled )
{
/* Reset Endpoint Frame ID to 0 */
ep->even_odd_frame = 0;
CLEAR_IN_EP_INTR(epnum, epdisabled);
}
}
epnum++;
ep_intr >>= 1;
}
/* Call user function */
INTR_INEPINTR_Callback();
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_OutEP_ISR
* Description : Handles all OUT endpoints interrupts.
* Input : None
* Output : None
* Return : Status
*******************************************************************************/
uint32_t OTGD_FS_Handle_OutEP_ISR(void)
{
uint32_t ep_intr = 0;
USB_OTG_dev_out_ep_int_data doepint;
uint32_t epnum = 0;
USB_OTG_EP *ep;
doepint.d32 = 0;
/* Read in the device interrupt bits */
ep_intr = OTGD_FS_ReadDevAllOutEp_itr();
while ( ep_intr )
{
if (ep_intr&0x1)
{
/* Get EP pointer */
ep = OTGD_FS_PCD_GetOutEP(epnum);
doepint.d32 = OTGD_FS_ReadDevOutEP_itr(ep);
/* Transfer complete */
if ( doepint.b.xfercompl )
{
/* Clear the bit in DOEPINTn for this interrupt */
CLEAR_OUT_EP_INTR(epnum, xfercompl);
if (epnum == 0)
{
/* Call the OUT process for the EP0 */
Out0_Process();
}
else
{
(*pEpInt_OUT[epnum-1])();
}
}
/* Endpoint disable */
if ( doepint.b.epdisabled )
{
/* Clear the bit in DOEPINTn for this interrupt */
CLEAR_OUT_EP_INTR(epnum, epdisabled);
}
/* AHB Error */
if ( doepint.b.ahberr )
{
CLEAR_OUT_EP_INTR(epnum, ahberr);
}
/* Setup Phase Done (control EPs) */
if ( doepint.b.setup )
{
if (epnum == 0)
{
/* Call the SETUP process for the EP0 */
Setup0_Process();
/* Before exit, update the Tx status */
OTG_DEV_SetEPTxStatus(0x80, SaveTState);
}
else
{
/* Other control endpoints */
}
/* Clear the EP Interrupt */
CLEAR_OUT_EP_INTR(epnum, setup);
}
}
epnum++;
ep_intr >>= 1;
}
/* Call user function */
INTR_OUTEPINTR_Callback();
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_IncomplIsoIn_ISR
* Description : Handles the Incomplete Isochrous IN tranfer error interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_IncomplIsoIn_ISR(void)
{
USB_OTG_int_sts_data gintsts;
gintsts.d32 = 0;
/* Call user function */
INTR_INCOMPLISOIN_Callback();
/* Clear interrupt */
gintsts.b.incomplisoin = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_IncomplIsoOut_ISR
* Description : Handles the Incomplete Isochrous OUT tranfer error interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_IncomplIsoOut_ISR(void)
{
USB_OTG_int_sts_data gintsts;
gintsts.d32 = 0;
/* Call user function */
INTR_INCOMPLISOOUT_Callback();
/* Clear interrupt */
gintsts.b.outepintr = 1;
WRITE_REG32(&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_Handle_Wakeup_ISR
* Description : Handles the Wakeup or Remote Wakeup detected interrupt.
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_Handle_Wakeup_ISR(void)
{
USB_OTG_int_sts_data gintsts;
gintsts.d32 = 0;
/* Call user function */
INTR_WKUPINTR_Callback();
/* Clear interrupt */
gintsts.b.wkupintr = 1;
WRITE_REG32 (&core_regs.common_regs->int_sts, gintsts.d32);
return 1;
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_GetDeviceSpeed
* Description : Get the device speed from the device status register
* Input : None
* Output : None
* Return : The Device speed value.
*******************************************************************************/
static enum usb_device_speed OTGD_FS_PCD_GetDeviceSpeed(void)
{
USB_OTG_dev_sts_data dsts;
enum usb_device_speed speed = USB_SPEED_UNKNOWN;
dsts.d32 = 0;
dsts.d32 = READ_REG32(&core_regs.dev_regs->dev_sts);
switch (dsts.b.enumspd)
{
case DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
speed = USB_SPEED_HIGH;
break;
case DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
case DSTS_ENUMSPD_FS_PHY_48MHZ:
speed = USB_SPEED_FULL;
break;
case DSTS_ENUMSPD_LS_PHY_6MHZ:
speed = USB_SPEED_LOW;
break;
}
return speed;
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_ReadDevInEP
* Description : Reads all the Endpoints flags.
* Input : None
* Output : None
* Return : Status
*******************************************************************************/
static uint32_t OTGD_FS_PCD_ReadDevInEP( USB_OTG_EP *ep)
{
uint32_t v = 0, msk = 0, emp=0;
msk = READ_REG32(&core_regs.dev_regs->dev_in_ep_msk);
emp = READ_REG32(&core_regs.dev_regs->dev_fifo_empty_msk);
msk |= ((emp >> ep->num) & 0x1) << 7;
v = READ_REG32(&core_regs.inep_regs[ep->num]->dev_in_ep_int) & msk;
return v;
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_WriteEmptyTxFifo
* Description : Checks Fifo for the next packet to be loaded.
* Input : None
* Output : None
* Return : Status
*******************************************************************************/
static uint32_t OTGD_FS_PCD_WriteEmptyTxFifo(uint32_t epnum)
{
USB_OTG_dev_tx_fifo_sts_data txstatus;
USB_OTG_EP *ep;
uint32_t len = 0;
uint32_t dwords = 0;
USB_OTG_dev_ep_ctl_data depctl;
txstatus.d32 = 0;
depctl.d32 = 0;
ep = OTGD_FS_PCD_GetInEP(epnum);
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
dwords = (len + 3) / 4;
txstatus.d32 = READ_REG32( &core_regs.inep_regs[epnum]->dev_tx_fifo_sts);
/* Manage the case of 0-length data packets toggling data PID */
if ((ep->xfer_len == 0) && (ep->xfer_count == 0))
{
if (ep->num > 0)
{
depctl.d32 = READ_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl);
if (ep->even_odd_frame == 1)
{
depctl.b.setd0pid = 0;
depctl.b.setd1pid = 1;
}
else
{
depctl.b.setd0pid = 1;
depctl.b.setd1pid = 0;
}
WRITE_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl, depctl.d32);
}
}
while ((txstatus.b.txfspcavail > dwords) &&
(ep->xfer_count < ep->xfer_len) &&
(ep->xfer_len) != 0)
{
if (ep->num > 0)
{
depctl.d32 = READ_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl);
if (ep->even_odd_frame == 0)
{
depctl.b.setd0pid = 1;
depctl.b.setd1pid = 0;
}
else
{
depctl.b.setd0pid = 0;
depctl.b.setd1pid = 1;
}
WRITE_REG32( &core_regs.inep_regs[epnum]->dev_in_ep_ctl, depctl.d32);
}
/* Write the FIFO */
len = ep->xfer_len - ep->xfer_count;
if (len > ep->maxpacket)
{
len = ep->maxpacket;
}
dwords = (len + 3) / 4;
OTGD_FS_WritePacket(ep->xfer_buff, epnum, len);
ep->xfer_count += len;
ep->xfer_buff += len;
txstatus.d32 = READ_REG32(&core_regs.inep_regs[epnum]->dev_tx_fifo_sts);
}
return 1;
}
#endif /* STM32F10X_CL */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,454 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : otgd_fs_pcd.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Peripheral Device Interface low layer.
********************************************************************************
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifdef STM32F10X_CL
#include "usb_lib.h"
#include "otgd_fs_cal.h"
#include "otgd_fs_pcd.h"
USB_OTG_PCD_DEV USB_OTG_PCD_dev;
extern USB_OTG_CORE_REGS core_regs;
/*******************************************************************************
* Function Name : OTGD_FS_PCD_Init
* Description : Initialize the USB Device portion of the driver.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void OTGD_FS_PCD_Init(void)
{
uint32_t i = 0;
USB_OTG_EP *ep;
ep = &USB_OTG_PCD_dev.ep0;
USB_OTG_PCD_dev.ep0state = 0;
/* Init ep structure */
ep->num = 0;
ep->tx_fifo_num = 0;
/* Control until ep is actvated */
ep->type = EP_TYPE_CTRL;
ep->maxpacket = MAX_PACKET_SIZE;
ep->xfer_buff = 0;
ep->xfer_len = 0;
for (i = 1; i < MAX_TX_FIFOS ; i++)
{
ep = &USB_OTG_PCD_dev.in_ep[i-1];
/* Init ep structure */
ep->is_in = 1;
ep->num = i;
ep->tx_fifo_num = i;
/* Control until ep is actvated */
ep->type = EP_TYPE_CTRL;
ep->maxpacket = MAX_PACKET_SIZE;
ep->xfer_buff = 0;
ep->xfer_len = 0;
}
for (i = 1; i < MAX_TX_FIFOS; i++)
{
ep = &USB_OTG_PCD_dev.out_ep[i-1];
/* Init ep structure */
ep->is_in = 0;
ep->num = i;
ep->tx_fifo_num = i;
/* Control until ep is activated */
ep->type = EP_TYPE_CTRL;
ep->maxpacket = MAX_PACKET_SIZE;
ep->xfer_buff = 0;
ep->xfer_len = 0;
}
USB_OTG_PCD_dev.ep0.maxpacket = MAX_EP0_SIZE;
USB_OTG_PCD_dev.ep0.type = EP_TYPE_CTRL;
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_EP_Open
* Description : Configure an Endpoint
* Input : None
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_PCD_EP_Open(EP_DESCRIPTOR *epdesc)
{
USB_OTG_EP *ep;
if ((0x80 & epdesc->bEndpointAddress) != 0)
{
ep = OTGD_FS_PCD_GetInEP(epdesc->bEndpointAddress & 0x7F);
ep->is_in = 1;
}
else
{
ep = OTGD_FS_PCD_GetOutEP(epdesc->bEndpointAddress & 0x7F);
ep->is_in = 0;
}
ep->num = epdesc->bEndpointAddress & 0x7F;
ep->maxpacket = epdesc->wMaxPacketSize;
ep->type = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
if (ep->is_in)
{
/* Assign a Tx FIFO */
ep->tx_fifo_num = ep->num;
}
/* Set initial data PID. */
if ((epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK )
{
ep->data_pid_start = 0;
}
OTGD_FS_EPActivate(ep );
return 0;
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_EP_Close
* Description : Called when an EP is disabled
* Input : Endpoint address.
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_PCD_EP_Close(uint8_t ep_addr)
{
USB_OTG_EP *ep;
if ((0x80 & ep_addr) != 0)
{
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
}
else
{
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
}
ep->num = ep_addr & 0x7F;
ep->is_in = (0x80 & ep_addr) != 0;
OTGD_FS_EPDeactivate(ep );
return 0;
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_EP_Read
* Description : Read data from Fifo
* Input : Endpoint address.
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_PCD_EP_Read (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
{
USB_OTG_EP *ep;
uint32_t i = 0;
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
/* copy received data into application buffer */
for (i = 0 ; i < buf_len ; i++)
{
pbuf[i] = ep->xfer_buff[i];
}
/*setup and start the Xfer */
ep->xfer_buff = pbuf;
ep->xfer_len = buf_len;
ep->xfer_count = 0;
ep->is_in = 0;
ep->num = ep_addr & 0x7F;
if ( ep->num == 0 )
{
OTGD_FS_EP0StartXfer(ep);
}
else if (USB_OTG_PCD_dev.ep0state == 0)
{
OTGD_FS_EPStartXfer( ep );
}
return 0;
}
/*******************************************************************************
* Function Name : USBF_EP_Write
* Description : Read data from Fifo
* Input : ep
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_PCD_EP_Write (uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
{
USB_OTG_EP *ep;
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7f);
/* assign data to EP structure buffer */
ep->xfer_buff = pbuf;
/* Setup and start the Transfer */
ep->xfer_count = 0;
ep->xfer_len = buf_len;
ep->is_in = 1;
ep->num = ep_addr & 0x7F;
if ( ep->num == 0 )
{
OTGD_FS_EP0StartXfer(ep);
}
else if (USB_OTG_PCD_dev.ep0state == 0)
{
OTGD_FS_EPStartXfer( ep );
}
return 0;
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_EP_Stall
* Description : Stall an endpoint.
* Input : Endpoint Address.
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_PCD_EP_Stall (uint8_t ep_addr)
{
USB_OTG_EP *ep;
if ((0x80 & ep_addr) != 0)
{
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
}
else
{
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
}
ep->num = ep_addr & 0x7F;
ep->is_in = ((ep_addr & 0x80) == 0x80) ? 1 : 0;
OTGD_FS_EPSetStall(ep);
return (0);
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_EP_ClrStall
* Description : Clear stall condition on endpoints.
* Input : Endpoint Address.
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_PCD_EP_ClrStall (uint8_t ep_addr)
{
USB_OTG_EP *ep;
if ((0x80 & ep_addr) != 0)
{
ep = OTGD_FS_PCD_GetInEP(ep_addr & 0x7F);
}
else
{
ep = OTGD_FS_PCD_GetOutEP(ep_addr & 0x7F);
}
ep->num = ep_addr & 0x7F;
ep->is_in = ((ep_addr & 0x80) == 0x80) ? 1 : 0;
OTGD_FS_EPClearStall(ep);
return (0);
}
/*******************************************************************************
* Function Name : USBF_FCD_EP_Flush()
* Description : This Function flushes the buffer.
* Input : Endpoint Address.
* Output : None
* Return : status
*******************************************************************************/
uint32_t OTGD_FS_PCD_EP_Flush (uint8_t ep_addr)
{
uint8_t is_out = 0;
uint8_t ep_nbr = 0;
ep_nbr = ep_addr & 0x7F;
is_out = ((ep_addr & 0x80) == 0x80) ? 0 : 1;
if (is_out == 0)
{
OTGD_FS_FlushTxFifo(ep_nbr);
}
else
{
OTGD_FS_FlushRxFifo();
}
OTGD_FS_PCD_EP_ClrStall(ep_addr);
return (0);
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_EP_SetAddress
* Description : This Function set USB device address
* Input : The new device Address to be set.
* Output : None
* Return : status
*******************************************************************************/
void OTGD_FS_PCD_EP_SetAddress (uint8_t address)
{
USB_OTG_dev_cfg_data dcfg;
dcfg.d32 = 0;
dcfg.b.devaddr = address;
MODIFY_REG32( &core_regs.dev_regs->dev_cfg, 0, dcfg.d32);
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_GetInEP
* Description : This function returns pointer to IN EP struct with number ep_num
* Input : Endpoint Number.
* Output : None
* Return : status
*******************************************************************************/
USB_OTG_EP* OTGD_FS_PCD_GetInEP(uint32_t ep_num)
{
uint32_t i = 0;
if (ep_num == 0)
{
return &USB_OTG_PCD_dev.ep0;
}
else
{
for (i = 0; i < MAX_TX_FIFOS; ++i)
{
if (USB_OTG_PCD_dev.in_ep[i].num == ep_num)
return &USB_OTG_PCD_dev.in_ep[i];
}
return 0;
}
}
/*******************************************************************************
* Function Name : USBF_GetOutEP
* Description : returns pointer to OUT EP struct with number ep_num
* Input : Endpoint Number.
* Output : None
* Return : USBF_EP
*******************************************************************************/
USB_OTG_EP* OTGD_FS_PCD_GetOutEP(uint32_t ep_num)
{
uint32_t i = 0;
if (ep_num == 0)
{
return &USB_OTG_PCD_dev.ep0;
}
else
{
for (i = 0; i < MAX_TX_FIFOS; ++i)
{
if (USB_OTG_PCD_dev.out_ep[i].num == ep_num)
return &USB_OTG_PCD_dev.out_ep[i];
}
return 0;
}
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_DevConnect
* Description : Connect device
* Input : None
* Output : None
* Return : status
*******************************************************************************/
void OTGD_FS_PCD_DevConnect(void)
{
USB_OTG_dev_ctl_data dctl;
dctl.d32 = 0;
dctl.d32 = READ_REG32(&core_regs.dev_regs->dev_ctl);
/* Connect device */
dctl.b.sftdiscon = 0;
WRITE_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32);
mDELAY(25);
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_DevDisconnect
* Description : Disconnect device
* Input : None
* Output : None
* Return : status
*******************************************************************************/
void OTGD_FS_PCD_DevDisconnect (void)
{
USB_OTG_dev_ctl_data dctl;
dctl.d32 = 0;
dctl.d32 = READ_REG32(&core_regs.dev_regs->dev_ctl);
/* Disconnect device for 20ms */
dctl.b.sftdiscon = 1;
WRITE_REG32(&core_regs.dev_regs->dev_ctl, dctl.d32);
mDELAY(25);
}
/*******************************************************************************
* Function Name : OTGD_FS_PCD_EP0_OutStart
* Description : Configures EPO to receive SETUP packets.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void OTGD_FS_PCD_EP0_OutStart(void)
{
USB_OTG_dev_ep_txfer_size0_data doeptsize0;
doeptsize0.d32 = 0;
doeptsize0.b.supcnt = 3;
doeptsize0.b.pktcnt = 1;
doeptsize0.b.xfersize = 8 * 3;
WRITE_REG32( &core_regs.outep_regs[0]->dev_out_ep_txfer_siz, doeptsize0.d32 );
}
#endif /* STM32F10X_CL */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@@ -1,63 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_init.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Initialization routines & global variables
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
uint8_t EPindex;
/* The number of current device, it is an index to the Device_Table */
/* uint8_t Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
DEVICE_INFO *pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
const DEVICE_PROP *pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
uint16_t SaveState ;
uint16_t wInterrupt_Mask;
DEVICE_INFO Device_Info;
const USER_STANDARD_REQUESTS *pUser_Standard_Requests;
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : USB_Init
* Description : USB system initialization
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void USB_Init(void)
{
pInformation = &Device_Info;
pInformation->ControlState = 2;
pProperty = &Device_Property;
pUser_Standard_Requests = &User_Standard_Requests;
/* Initialize devices one by one */
pProperty->Init();
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,188 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_int.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Endpoint CTR (Low and High) interrupt's service routines
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifndef STM32F10X_CL
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t SaveRState;
__IO uint16_t SaveTState;
/* Extern variables ----------------------------------------------------------*/
extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */
extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : CTR_LP.
* Description : Low priority Endpoint Correct Transfer interrupt's service
* routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void CTR_LP(void)
{
__IO uint16_t wEPVal = 0;
/* stay in loop while pending ints */
while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
{
/* extract highest priority endpoint number */
EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
if (EPindex == 0)
{
/* Decode and service control endpoint interrupt */
/* calling related service routine */
/* (Setup0_Process, In0_Process, Out0_Process) */
/* save RX & TX status */
/* and set both to NAK */
SaveRState = _GetENDPOINT(ENDP0);
SaveTState = SaveRState & EPTX_STAT;
SaveRState &= EPRX_STAT;
_SetEPRxTxStatus(ENDP0,EP_RX_NAK,EP_TX_NAK);
/* DIR bit = origin of the interrupt */
if ((wIstr & ISTR_DIR) == 0)
{
/* DIR = 0 */
/* DIR = 0 => IN int */
/* DIR = 0 implies that (EP_CTR_TX = 1) always */
_ClearEP_CTR_TX(ENDP0);
In0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
else
{
/* DIR = 1 */
/* DIR = 1 & CTR_RX => SETUP or OUT int */
/* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
wEPVal = _GetENDPOINT(ENDP0);
if ((wEPVal &EP_SETUP) != 0)
{
_ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
Setup0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
else if ((wEPVal & EP_CTR_RX) != 0)
{
_ClearEP_CTR_RX(ENDP0);
Out0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxTxStatus(ENDP0,SaveRState,SaveTState);
return;
}
}
}/* if(EPindex == 0) */
else
{
/* Decode and service non control endpoints interrupt */
/* process related endpoint register */
wEPVal = _GetENDPOINT(EPindex);
if ((wEPVal & EP_CTR_RX) != 0)
{
/* clear int flag */
_ClearEP_CTR_RX(EPindex);
/* call OUT service function */
(*pEpInt_OUT[EPindex-1])();
} /* if((wEPVal & EP_CTR_RX) */
if ((wEPVal & EP_CTR_TX) != 0)
{
/* clear int flag */
_ClearEP_CTR_TX(EPindex);
/* call IN service function */
(*pEpInt_IN[EPindex-1])();
} /* if((wEPVal & EP_CTR_TX) != 0) */
}/* if(EPindex == 0) else */
}/* while(...) */
}
/*******************************************************************************
* Function Name : CTR_HP.
* Description : High Priority Endpoint Correct Transfer interrupt's service
* routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void CTR_HP(void)
{
uint32_t wEPVal = 0;
while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
{
_SetISTR((uint16_t)CLR_CTR); /* clear CTR flag */
/* extract highest priority endpoint number */
EPindex = (uint8_t)(wIstr & ISTR_EP_ID);
/* process related endpoint register */
wEPVal = _GetENDPOINT(EPindex);
if ((wEPVal & EP_CTR_RX) != 0)
{
/* clear int flag */
_ClearEP_CTR_RX(EPindex);
/* call OUT service function */
(*pEpInt_OUT[EPindex-1])();
} /* if((wEPVal & EP_CTR_RX) */
else if ((wEPVal & EP_CTR_TX) != 0)
{
/* clear int flag */
_ClearEP_CTR_TX(EPindex);
/* call IN service function */
(*pEpInt_IN[EPindex-1])();
} /* if((wEPVal & EP_CTR_TX) != 0) */
}/* while(...) */
}
#endif /* STM32F10X_CL */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,75 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_mem.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Utility functions for memory transfers to/from PMA
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifndef STM32F10X_CL
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : UserToPMABufferCopy
* Description : Copy a buffer from user memory area to packet memory area (PMA)
* Input : - pbUsrBuf: pointer to user memory area.
* - wPMABufAddr: address into PMA.
* - wNBytes: no. of bytes to be copied.
* Output : None.
* Return : None .
*******************************************************************************/
void UserToPMABufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */
uint32_t i, temp1, temp2;
uint16_t *pdwVal;
pdwVal = (uint16_t *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i--)
{
temp1 = (uint16_t) * pbUsrBuf;
pbUsrBuf++;
temp2 = temp1 | (uint16_t) * pbUsrBuf << 8;
*pdwVal++ = temp2;
pdwVal++;
pbUsrBuf++;
}
}
/*******************************************************************************
* Function Name : PMAToUserBufferCopy
* Description : Copy a buffer from user memory area to packet memory area (PMA)
* Input : - pbUsrBuf = pointer to user memory area.
* - wPMABufAddr = address into PMA.
* - wNBytes = no. of bytes to be copied.
* Output : None.
* Return : None.
*******************************************************************************/
void PMAToUserBufferCopy(uint8_t *pbUsrBuf, uint16_t wPMABufAddr, uint16_t wNBytes)
{
uint32_t n = (wNBytes + 1) >> 1;/* /2*/
uint32_t i;
uint32_t *pdwVal;
pdwVal = (uint32_t *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i--)
{
*(uint16_t*)pbUsrBuf++ = *pdwVal++;
pbUsrBuf++;
}
}
#endif /* STM32F10X_CL */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,750 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_regs.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Interface functions to USB cell registers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
#ifndef STM32F10X_CL
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : SetCNTR.
* Description : Set the CNTR register value.
* Input : wRegValue: new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetCNTR(uint16_t wRegValue)
{
_SetCNTR(wRegValue);
}
/*******************************************************************************
* Function Name : GetCNTR.
* Description : returns the CNTR register value.
* Input : None.
* Output : None.
* Return : CNTR register Value.
*******************************************************************************/
uint16_t GetCNTR(void)
{
return(_GetCNTR());
}
/*******************************************************************************
* Function Name : SetISTR.
* Description : Set the ISTR register value.
* Input : wRegValue: new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetISTR(uint16_t wRegValue)
{
_SetISTR(wRegValue);
}
/*******************************************************************************
* Function Name : GetISTR
* Description : Returns the ISTR register value.
* Input : None.
* Output : None.
* Return : ISTR register Value
*******************************************************************************/
uint16_t GetISTR(void)
{
return(_GetISTR());
}
/*******************************************************************************
* Function Name : GetFNR
* Description : Returns the FNR register value.
* Input : None.
* Output : None.
* Return : FNR register Value
*******************************************************************************/
uint16_t GetFNR(void)
{
return(_GetFNR());
}
/*******************************************************************************
* Function Name : SetDADDR
* Description : Set the DADDR register value.
* Input : wRegValue: new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetDADDR(uint16_t wRegValue)
{
_SetDADDR(wRegValue);
}
/*******************************************************************************
* Function Name : GetDADDR
* Description : Returns the DADDR register value.
* Input : None.
* Output : None.
* Return : DADDR register Value
*******************************************************************************/
uint16_t GetDADDR(void)
{
return(_GetDADDR());
}
/*******************************************************************************
* Function Name : SetBTABLE
* Description : Set the BTABLE.
* Input : wRegValue: New register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetBTABLE(uint16_t wRegValue)
{
_SetBTABLE(wRegValue);
}
/*******************************************************************************
* Function Name : GetBTABLE.
* Description : Returns the BTABLE register value.
* Input : None.
* Output : None.
* Return : BTABLE address.
*******************************************************************************/
uint16_t GetBTABLE(void)
{
return(_GetBTABLE());
}
/*******************************************************************************
* Function Name : SetENDPOINT
* Description : Setthe Endpoint register value.
* Input : bEpNum: Endpoint Number.
* wRegValue.
* Output : None.
* Return : None.
*******************************************************************************/
void SetENDPOINT(uint8_t bEpNum, uint16_t wRegValue)
{
_SetENDPOINT(bEpNum, wRegValue);
}
/*******************************************************************************
* Function Name : GetENDPOINT
* Description : Return the Endpoint register value.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint register value.
*******************************************************************************/
uint16_t GetENDPOINT(uint8_t bEpNum)
{
return(_GetENDPOINT(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPType
* Description : sets the type in the endpoint register.
* Input : bEpNum: Endpoint Number.
* wType: type definition.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPType(uint8_t bEpNum, uint16_t wType)
{
_SetEPType(bEpNum, wType);
}
/*******************************************************************************
* Function Name : GetEPType
* Description : Returns the endpoint type.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Type
*******************************************************************************/
uint16_t GetEPType(uint8_t bEpNum)
{
return(_GetEPType(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxStatus
* Description : Set the status of Tx endpoint.
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxStatus(uint8_t bEpNum, uint16_t wState)
{
_SetEPTxStatus(bEpNum, wState);
}
/*******************************************************************************
* Function Name : SetEPRxStatus
* Description : Set the status of Rx endpoint.
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxStatus(uint8_t bEpNum, uint16_t wState)
{
_SetEPRxStatus(bEpNum, wState);
}
/*******************************************************************************
* Function Name : SetDouBleBuffEPStall
* Description : sets the status for Double Buffer Endpoint to STALL
* Input : bEpNum: Endpoint Number.
* bDir: Endpoint direction.
* Output : None.
* Return : None.
*******************************************************************************/
void SetDouBleBuffEPStall(uint8_t bEpNum, uint8_t bDir)
{
uint16_t Endpoint_DTOG_Status;
Endpoint_DTOG_Status = GetENDPOINT(bEpNum);
if (bDir == EP_DBUF_OUT)
{ /* OUT double buffered endpoint */
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1);
}
else if (bDir == EP_DBUF_IN)
{ /* IN double buffered endpoint */
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1);
}
}
/*******************************************************************************
* Function Name : GetEPTxStatus
* Description : Returns the endpoint Tx status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint TX Status
*******************************************************************************/
uint16_t GetEPTxStatus(uint8_t bEpNum)
{
return(_GetEPTxStatus(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPRxStatus
* Description : Returns the endpoint Rx status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint RX Status
*******************************************************************************/
uint16_t GetEPRxStatus(uint8_t bEpNum)
{
return(_GetEPRxStatus(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxValid
* Description : Valid the endpoint Tx Status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxValid(uint8_t bEpNum)
{
_SetEPTxStatus(bEpNum, EP_TX_VALID);
}
/*******************************************************************************
* Function Name : SetEPRxValid
* Description : Valid the endpoint Rx Status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxValid(uint8_t bEpNum)
{
_SetEPRxStatus(bEpNum, EP_RX_VALID);
}
/*******************************************************************************
* Function Name : SetEP_KIND
* Description : Clear the EP_KIND bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEP_KIND(uint8_t bEpNum)
{
_SetEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : ClearEP_KIND
* Description : set the EP_KIND bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEP_KIND(uint8_t bEpNum)
{
_ClearEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : Clear_Status_Out
* Description : Clear the Status Out of the related Endpoint
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void Clear_Status_Out(uint8_t bEpNum)
{
_ClearEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : Set_Status_Out
* Description : Set the Status Out of the related Endpoint
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void Set_Status_Out(uint8_t bEpNum)
{
_SetEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : SetEPDoubleBuff
* Description : Enable the double buffer feature for the endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDoubleBuff(uint8_t bEpNum)
{
_SetEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : ClearEPDoubleBuff
* Description : Disable the double buffer feature for the endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEPDoubleBuff(uint8_t bEpNum)
{
_ClearEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : GetTxStallStatus
* Description : Returns the Stall status of the Tx endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Tx Stall status.
*******************************************************************************/
uint16_t GetTxStallStatus(uint8_t bEpNum)
{
return(_GetTxStallStatus(bEpNum));
}
/*******************************************************************************
* Function Name : GetRxStallStatus
* Description : Returns the Stall status of the Rx endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx Stall status.
*******************************************************************************/
uint16_t GetRxStallStatus(uint8_t bEpNum)
{
return(_GetRxStallStatus(bEpNum));
}
/*******************************************************************************
* Function Name : ClearEP_CTR_RX
* Description : Clear the CTR_RX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEP_CTR_RX(uint8_t bEpNum)
{
_ClearEP_CTR_RX(bEpNum);
}
/*******************************************************************************
* Function Name : ClearEP_CTR_TX
* Description : Clear the CTR_TX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEP_CTR_TX(uint8_t bEpNum)
{
_ClearEP_CTR_TX(bEpNum);
}
/*******************************************************************************
* Function Name : ToggleDTOG_RX
* Description : Toggle the DTOG_RX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ToggleDTOG_RX(uint8_t bEpNum)
{
_ToggleDTOG_RX(bEpNum);
}
/*******************************************************************************
* Function Name : ToggleDTOG_TX
* Description : Toggle the DTOG_TX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ToggleDTOG_TX(uint8_t bEpNum)
{
_ToggleDTOG_TX(bEpNum);
}
/*******************************************************************************
* Function Name : ClearDTOG_RX.
* Description : Clear the DTOG_RX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearDTOG_RX(uint8_t bEpNum)
{
_ClearDTOG_RX(bEpNum);
}
/*******************************************************************************
* Function Name : ClearDTOG_TX.
* Description : Clear the DTOG_TX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearDTOG_TX(uint8_t bEpNum)
{
_ClearDTOG_TX(bEpNum);
}
/*******************************************************************************
* Function Name : SetEPAddress
* Description : Set the endpoint address.
* Input : bEpNum: Endpoint Number.
* bAddr: New endpoint address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPAddress(uint8_t bEpNum, uint8_t bAddr)
{
_SetEPAddress(bEpNum, bAddr);
}
/*******************************************************************************
* Function Name : GetEPAddress
* Description : Get the endpoint address.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint address.
*******************************************************************************/
uint8_t GetEPAddress(uint8_t bEpNum)
{
return(_GetEPAddress(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxAddr
* Description : Set the endpoint Tx buffer address.
* Input : bEpNum: Endpoint Number.
* wAddr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxAddr(uint8_t bEpNum, uint16_t wAddr)
{
_SetEPTxAddr(bEpNum, wAddr);
}
/*******************************************************************************
* Function Name : SetEPRxAddr
* Description : Set the endpoint Rx buffer address.
* Input : bEpNum: Endpoint Number.
* wAddr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxAddr(uint8_t bEpNum, uint16_t wAddr)
{
_SetEPRxAddr(bEpNum, wAddr);
}
/*******************************************************************************
* Function Name : GetEPTxAddr
* Description : Returns the endpoint Tx buffer address.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx buffer address.
*******************************************************************************/
uint16_t GetEPTxAddr(uint8_t bEpNum)
{
return(_GetEPTxAddr(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPRxAddr.
* Description : Returns the endpoint Rx buffer address.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx buffer address.
*******************************************************************************/
uint16_t GetEPRxAddr(uint8_t bEpNum)
{
return(_GetEPRxAddr(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxCount.
* Description : Set the Tx count.
* Input : bEpNum: Endpoint Number.
* wCount: new count value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxCount(uint8_t bEpNum, uint16_t wCount)
{
_SetEPTxCount(bEpNum, wCount);
}
/*******************************************************************************
* Function Name : SetEPCountRxReg.
* Description : Set the Count Rx Register value.
* Input : *pdwReg: point to the register.
* wCount: the new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPCountRxReg(uint32_t *pdwReg, uint16_t wCount)
{
_SetEPCountRxReg(dwReg, wCount);
}
/*******************************************************************************
* Function Name : SetEPRxCount
* Description : Set the Rx count.
* Input : bEpNum: Endpoint Number.
* wCount: the new count value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxCount(uint8_t bEpNum, uint16_t wCount)
{
_SetEPRxCount(bEpNum, wCount);
}
/*******************************************************************************
* Function Name : GetEPTxCount
* Description : Get the Tx count.
* Input : bEpNum: Endpoint Number.
* Output : None
* Return : Tx count value.
*******************************************************************************/
uint16_t GetEPTxCount(uint8_t bEpNum)
{
return(_GetEPTxCount(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPRxCount
* Description : Get the Rx count.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx count value.
*******************************************************************************/
uint16_t GetEPRxCount(uint8_t bEpNum)
{
return(_GetEPRxCount(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPDblBuffAddr
* Description : Set the addresses of the buffer 0 and 1.
* Input : bEpNum: Endpoint Number.
* wBuf0Addr: new address of buffer 0.
* wBuf1Addr: new address of buffer 1.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuffAddr(uint8_t bEpNum, uint16_t wBuf0Addr, uint16_t wBuf1Addr)
{
_SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr);
}
/*******************************************************************************
* Function Name : SetEPDblBuf0Addr
* Description : Set the Buffer 1 address.
* Input : bEpNum: Endpoint Number
* wBuf0Addr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf0Addr(uint8_t bEpNum, uint16_t wBuf0Addr)
{
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);
}
/*******************************************************************************
* Function Name : SetEPDblBuf1Addr
* Description : Set the Buffer 1 address.
* Input : bEpNum: Endpoint Number
* wBuf1Addr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf1Addr(uint8_t bEpNum, uint16_t wBuf1Addr)
{
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);
}
/*******************************************************************************
* Function Name : GetEPDblBuf0Addr
* Description : Returns the address of the Buffer 0.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
uint16_t GetEPDblBuf0Addr(uint8_t bEpNum)
{
return(_GetEPDblBuf0Addr(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPDblBuf1Addr
* Description : Returns the address of the Buffer 1.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Address of the Buffer 1.
*******************************************************************************/
uint16_t GetEPDblBuf1Addr(uint8_t bEpNum)
{
return(_GetEPDblBuf1Addr(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPDblBuffCount
* Description : Set the number of bytes for a double Buffer
* endpoint.
* Input : bEpNum,bDir, wCount
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuffCount(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
{
_SetEPDblBuffCount(bEpNum, bDir, wCount);
}
/*******************************************************************************
* Function Name : SetEPDblBuf0Count
* Description : Set the number of bytes in the buffer 0 of a double Buffer
* endpoint.
* Input : bEpNum, bDir, wCount
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf0Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
{
_SetEPDblBuf0Count(bEpNum, bDir, wCount);
}
/*******************************************************************************
* Function Name : SetEPDblBuf1Count
* Description : Set the number of bytes in the buffer 0 of a double Buffer
* endpoint.
* Input : bEpNum, bDir, wCount
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf1Count(uint8_t bEpNum, uint8_t bDir, uint16_t wCount)
{
_SetEPDblBuf1Count(bEpNum, bDir, wCount);
}
/*******************************************************************************
* Function Name : GetEPDblBuf0Count
* Description : Returns the number of byte received in the buffer 0 of a double
* Buffer endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Buffer 0 count
*******************************************************************************/
uint16_t GetEPDblBuf0Count(uint8_t bEpNum)
{
return(_GetEPDblBuf0Count(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPDblBuf1Count
* Description : Returns the number of data received in the buffer 1 of a double
* Buffer endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Buffer 1 count.
*******************************************************************************/
uint16_t GetEPDblBuf1Count(uint8_t bEpNum)
{
return(_GetEPDblBuf1Count(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPDblBufDir
* Description : gets direction of the double buffered endpoint
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : EP_DBUF_OUT, EP_DBUF_IN,
* EP_DBUF_ERR if the endpoint counter not yet programmed.
*******************************************************************************/
EP_DBUF_DIR GetEPDblBufDir(uint8_t bEpNum)
{
if ((uint16_t)(*_pEPRxCount(bEpNum) & 0xFC00) != 0)
return(EP_DBUF_OUT);
else if (((uint16_t)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0)
return(EP_DBUF_IN);
else
return(EP_DBUF_ERR);
}
/*******************************************************************************
* Function Name : FreeUserBuffer
* Description : free buffer used from the application realizing it to the line
toggles bit SW_BUF in the double buffered endpoint register
* Input : bEpNum, bDir
* Output : None.
* Return : None.
*******************************************************************************/
void FreeUserBuffer(uint8_t bEpNum, uint8_t bDir)
{
if (bDir == EP_DBUF_OUT)
{ /* OUT double buffered endpoint */
_ToggleDTOG_TX(bEpNum);
}
else if (bDir == EP_DBUF_IN)
{ /* IN double buffered endpoint */
_ToggleDTOG_RX(bEpNum);
}
}
/*******************************************************************************
* Function Name : ToWord
* Description : merge two byte in a word.
* Input : bh: byte high, bl: bytes low.
* Output : None.
* Return : resulted word.
*******************************************************************************/
uint16_t ToWord(uint8_t bh, uint8_t bl)
{
uint16_t wRet;
wRet = (uint16_t)bl | ((uint16_t)bh << 8);
return(wRet);
}
/*******************************************************************************
* Function Name : ByteSwap
* Description : Swap two byte in a word.
* Input : wSwW: word to Swap.
* Output : None.
* Return : resulted word.
*******************************************************************************/
uint16_t ByteSwap(uint16_t wSwW)
{
uint8_t bTemp;
uint16_t wRet;
bTemp = (uint8_t)(wSwW & 0xff);
wRet = (wSwW >> 8) | ((uint16_t)bTemp << 8);
return(wRet);
}
#endif /* STM32F10X_CL */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,126 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_sil.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Simplified Interface Layer for Global Initialization and
* Endpoint Rea/Write operations.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : USB_SIL_Init
* Description : Initialize the USB Device IP and the Endpoint 0.
* Input : None.
* Output : None.
* Return : Status.
*******************************************************************************/
uint32_t USB_SIL_Init(void)
{
#ifndef STM32F10X_CL
/* USB interrupts initialization */
/* clear pending interrupts */
_SetISTR(0);
wInterrupt_Mask = IMR_MSK;
/* set interrupts mask */
_SetCNTR(wInterrupt_Mask);
#else
/* Perform OTG Device initialization procedure (including EP0 init) */
OTG_DEV_Init();
#endif /* STM32F10X_CL */
return 0;
}
/*******************************************************************************
* Function Name : USB_SIL_Write
* Description : Write a buffer of data to a selected endpoint.
* Input : - bEpAddr: The address of the non control endpoint.
* - pBufferPointer: The pointer to the buffer of data to be written
* to the endpoint.
* - wBufferSize: Number of data to be written (in bytes).
* Output : None.
* Return : Status.
*******************************************************************************/
uint32_t USB_SIL_Write(uint8_t bEpAddr, uint8_t* pBufferPointer, uint32_t wBufferSize)
{
#ifndef STM32F10X_CL
/* Use the memory interface function to write to the selected endpoint */
UserToPMABufferCopy(pBufferPointer, GetEPTxAddr(bEpAddr & 0x7F), wBufferSize);
/* Update the data length in the control register */
SetEPTxCount((bEpAddr & 0x7F), wBufferSize);
#else
/* Use the PCD interface layer function to write to the selected endpoint */
OTGD_FS_PCD_EP_Write (bEpAddr, pBufferPointer, wBufferSize);
#endif /* STM32F10X_CL */
return 0;
}
/*******************************************************************************
* Function Name : USB_SIL_Read
* Description : Write a buffer of data to a selected endpoint.
* Input : - bEpAddr: The address of the non control endpoint.
* - pBufferPointer: The pointer to which will be saved the
* received data buffer.
* Output : None.
* Return : Number of received data (in Bytes).
*******************************************************************************/
uint32_t USB_SIL_Read(uint8_t bEpAddr, uint8_t* pBufferPointer)
{
uint32_t DataLength = 0;
#ifndef STM32F10X_CL
/* Get the number of received data on the selected Endpoint */
DataLength = GetEPRxCount(bEpAddr & 0x7F);
/* Use the memory interface function to write to the selected endpoint */
PMAToUserBufferCopy(pBufferPointer, GetEPRxAddr(bEpAddr & 0x7F), DataLength);
#else
USB_OTG_EP *ep;
/* Get the structure pointer of the selected Endpoint */
ep = OTGD_FS_PCD_GetOutEP(bEpAddr);
/* Get the number of received data */
DataLength = ep->xfer_len;
/* Use the PCD interface layer function to read the selected endpoint */
OTGD_FS_PCD_EP_Read (bEpAddr, pBufferPointer, DataLength);
#endif /* STM32F10X_CL */
/* Return the number of received data */
return DataLength;
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,113 +0,0 @@
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name : hw_config.c
* Author : MCD Application Team
* Version : V3.0.1
* Date : 04/27/2009
* Description : Hardware Configuration & Setup
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "hw_config.h"
#include "platform_config.h"
#include "usb_pwr.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : Enter_LowPowerMode
* Description : Power-off system clocks and power while entering suspend mode
* Input : None.
* Return : None.
*******************************************************************************/
void Enter_LowPowerMode(void)
{
/* Set the device state to suspend */
bDeviceState = SUSPENDED;
}
/*******************************************************************************
* Function Name : Leave_LowPowerMode
* Description : Restores system clocks and power while exiting suspend mode
* Input : None.
* Return : None.
*******************************************************************************/
void Leave_LowPowerMode(void)
{
DEVICE_INFO *pInfo = &Device_Info;
/* Set the device state to the correct state */
if (pInfo->Current_Configuration != 0) {
/* Device configured */
bDeviceState = CONFIGURED;
} else {
bDeviceState = ATTACHED;
}
}
/*******************************************************************************
* Function Name : USB_Cable_Config
* Description : Software Connection/Disconnection of USB Cable
* Input : None.
* Return : Status
*******************************************************************************/
void USB_Cable_Config (FunctionalState NewState)
{
if (NewState != DISABLE) {
GPIO_ResetBits(GPIOC, GPIO_Pin_11);
} else {
GPIO_SetBits(GPIOC, GPIO_Pin_11);
}
}
/*******************************************************************************
* Function Name : Get_SerialNum.
* Description : Create the serial number string descriptor.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Get_SerialNum(void)
{
uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
/*
Device_Serial0 = *(__IO uint32_t*)(0x1FFFF7E8);
Device_Serial1 = *(__IO uint32_t*)(0x1FFFF7EC);
Device_Serial2 = *(__IO uint32_t*)(0x1FFFF7F0);
if (Device_Serial0 != 0)
{
Virtual_Com_Port_StringSerial[2] = (uint8_t)(Device_Serial0 & 0x000000FF);
Virtual_Com_Port_StringSerial[4] = (uint8_t)((Device_Serial0 & 0x0000FF00) >> 8);
Virtual_Com_Port_StringSerial[6] = (uint8_t)((Device_Serial0 & 0x00FF0000) >> 16);
Virtual_Com_Port_StringSerial[8] = (uint8_t)((Device_Serial0 & 0xFF000000) >> 24);
Virtual_Com_Port_StringSerial[10] = (uint8_t)(Device_Serial1 & 0x000000FF);
Virtual_Com_Port_StringSerial[12] = (uint8_t)((Device_Serial1 & 0x0000FF00) >> 8);
Virtual_Com_Port_StringSerial[14] = (uint8_t)((Device_Serial1 & 0x00FF0000) >> 16);
Virtual_Com_Port_StringSerial[16] = (uint8_t)((Device_Serial1 & 0xFF000000) >> 24);
Virtual_Com_Port_StringSerial[18] = (uint8_t)(Device_Serial2 & 0x000000FF);
Virtual_Com_Port_StringSerial[20] = (uint8_t)((Device_Serial2 & 0x0000FF00) >> 8);
Virtual_Com_Port_StringSerial[22] = (uint8_t)((Device_Serial2 & 0x00FF0000) >> 16);
Virtual_Com_Port_StringSerial[24] = (uint8_t)((Device_Serial2 & 0xFF000000) >> 24);
}*/
}
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -1,41 +0,0 @@
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name : hw_config.h
* Author : MCD Application Team
* Version : V3.0.1
* Date : 04/27/2009
* Description : Hardware Configuration & Setup
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __HW_CONFIG_H
#define __HW_CONFIG_H
/* Includes ------------------------------------------------------------------*/
#include "usb_type.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported define -----------------------------------------------------------*/
#define MASS_MEMORY_START 0x04002000
#define BULK_MAX_PACKET_SIZE 0x00000040
#define LED_ON 0xF0
#define LED_OFF 0xFF
/* Exported functions ------------------------------------------------------- */
void Enter_LowPowerMode(void);
void Leave_LowPowerMode(void);
void USB_Cable_Config (FunctionalState NewState);
void Get_SerialNum(void);
/* External variables --------------------------------------------------------*/
#endif /*__HW_CONFIG_H*/
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -1,57 +0,0 @@
#ifndef PLATFORM_H_
#define PLATFORM_H_
#define LED_PIN GPIO_Pin_12
#define LED_GPIO GPIOC
#define LCD_E_PIN GPIO_Pin_10
#define LCD_E_GPIO GPIOC
#define LCD_RESET_PIN GPIO_Pin_7
#define LCD_RESET_GPIO GPIOC
#define LCD_DC_PIN GPIO_Pin_2
#define LCD_DC_GPIO GPIOB
#define TAMP_PIN GPIO_Pin_13
#define TAMP_GPIO GPIOC
#define WAKE_PIN GPIO_Pin_0
#define WAKE_GPIO GPIOA
#define JOY_CENTER_PIN GPIO_Pin_6
#define JOY_CENTER_GPIO GPIOC
#define NRF_CS_PIN GPIO_Pin_4
#define NRF_CS_GPIO GPIOA
#define NRF_CE_PIN GPIO_Pin_8
#define NRF_CE_GPIO GPIOC
#define NRF_IRQ_PIN GPIO_Pin_9
#define NRF_IRQ_GPIO GPIOC
#define ADIS_CS_PIN GPIO_Pin_10
#define ADIS_CS_GPIO GPIOB
#define ADIS_RESET_PIN GPIO_Pin_3
#define ADIS_RESET_GPIO GPIOA
#define LED_WRITE(x) GPIO_WriteBit(LED_GPIO, LED_PIN, x)
#define LCD_DC_WRITE(x) GPIO_WriteBit(LCD_DC_GPIO, LCD_DC_PIN, x)
#define LCD_E_WRITE(x) GPIO_WriteBit(LCD_E_GPIO, LCD_E_PIN, x)
#define LCD_RESET_WRITE(x) GPIO_WriteBit(LCD_RESET_GPIO, LCD_RESET_PIN, x)
#define TAMP_READ GPIO_ReadInputDataBit(TAMP_GPIO, TAMP_PIN)
#define WAKE_READ GPIO_ReadInputDataBit(WAKE_GPIO, WAKE_PIN)
#define JOY_CENTER_READ GPIO_ReadInputDataBit(JOY_CENTER_GPIO, JOY_CENTER_PIN)
#define NRF_CE_WRITE(x) GPIO_WriteBit(NRF_CE_GPIO, NRF_CE_PIN, x)
#define NRF_CS_WRITE(x) GPIO_WriteBit(NRF_CS_GPIO, NRF_CS_PIN, x)
#define NRF_IRQ_READ GPIO_ReadInputDataBit(MRF_IRQ_GPIO, NRF_IRQ_PIN)
#define ADIS_CS_WRITE(x) GPIO_WriteBit(ADIS_CS_GPIO, ADIS_CS_PIN, x)
#define ADIS_RESET_WRITE(x) GPIO_WriteBit(ADIS_RESET_GPIO, ADIS_RESET_PIN, x)
#endif

View File

@@ -1,52 +0,0 @@
/******************** (C) COPYRIGHT 2009 STMicroelectronics ********************
* File Name : platform_config.h
* Author : MCD Application Team
* Version : V3.0.1
* Date : 04/27/2009
* Description : Evaluation board specific configuration file.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __PLATFORM_CONFIG_H
#define __PLATFORM_CONFIG_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Uncomment the line corresponding to the STMicroelectronics evaluation board
used to run the example */
#if !defined (USE_STM3210B_EVAL) && !defined (USE_STM3210E_EVAL)
//#define USE_STM3210B_EVAL
#define USE_STM3210E_EVAL
#endif
/* Define the STM32F10x hardware depending on the used evaluation board */
#ifdef USE_STM3210B_EVAL
#define USB_DISCONNECT GPIOD
#define USB_DISCONNECT_PIN GPIO_Pin_9
#define RCC_APB2Periph_GPIO_DISCONNECT RCC_APB2Periph_GPIOD
#else /* USE_STM3210E_EVAL */
#define USB_DISCONNECT GPIOB
#define USB_DISCONNECT_PIN GPIO_Pin_14
#define RCC_APB2Periph_GPIO_DISCONNECT RCC_APB2Periph_GPIOB
#endif /* USE_STM3210B_EVAL */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __PLATFORM_CONFIG_H */
/******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/

View File

@@ -1,197 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_conf.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Virtual COM Port Demo configuration header
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CONF_H
#define __USB_CONF_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
/*-------------------------------------------------------------*/
/* EP_NUM */
/* defines how many endpoints are used by the device */
/*-------------------------------------------------------------*/
#define EP_NUM (4)
#ifndef STM32F10X_CL
/*-------------------------------------------------------------*/
/* -------------- Buffer Description Table -----------------*/
/*-------------------------------------------------------------*/
/* buffer table base address */
/* buffer table base address */
#define BTABLE_ADDRESS (0x00)
/* EP0 */
/* rx/tx buffer base address */
#define ENDP0_RXADDR (0x40)
#define ENDP0_TXADDR (0x80)
/* EP1 */
/* tx buffer base address */
#define ENDP1_TXADDR (0xC0)
#define ENDP2_TXADDR (0x100)
#define ENDP3_RXADDR (0x110)
/*-------------------------------------------------------------*/
/* ------------------- ISTR events -------------------------*/
/*-------------------------------------------------------------*/
/* IMR_MSK */
/* mask defining which events has to be handled */
/* by the device application software */
#define IMR_MSK (CNTR_CTRM | CNTR_SOFM | CNTR_RESETM )
/*#define CTR_CALLBACK*/
/*#define DOVR_CALLBACK*/
/*#define ERR_CALLBACK*/
/*#define WKUP_CALLBACK*/
/*#define SUSP_CALLBACK*/
/*#define RESET_CALLBACK*/
/*#define SOF_CALLBACK*/
/*#define ESOF_CALLBACK*/
#endif /* STM32F10X_CL */
#ifdef STM32F10X_CL
/*******************************************************************************
* FIFO Size Configuration
*
* (i) Dedicated data FIFO SPRAM of 1.25 Kbytes = 1280 bytes = 320 32-bits words
* available for the endpoints IN and OUT.
* Device mode features:
* -1 bidirectional CTRL EP 0
* -3 IN EPs to support any kind of Bulk, Interrupt or Isochronous transfer
* -3 OUT EPs to support any kind of Bulk, Interrupt or Isochronous transfer
*
* ii) Receive data FIFO size = RAM for setup packets +
* OUT endpoint control information +
* data OUT packets + miscellaneous
* Space = ONE 32-bits words
* --> RAM for setup packets = 4 * n + 6 space
* (n is the nbr of CTRL EPs the device core supports)
* --> OUT EP CTRL info = 1 space
* (one space for status information written to the FIFO along with each
* received packet)
* --> data OUT packets = (Largest Packet Size / 4) + 1 spaces
* (MINIMUM to receive packets)
* --> OR data OUT packets = at least 2*(Largest Packet Size / 4) + 1 spaces
* (if high-bandwidth EP is enabled or multiple isochronous EPs)
* --> miscellaneous = 1 space per OUT EP
* (one space for transfer complete status information also pushed to the
* FIFO with each endpoint's last packet)
*
* (iii)MINIMUM RAM space required for each IN EP Tx FIFO = MAX packet size for
* that particular IN EP. More space allocated in the IN EP Tx FIFO results
* in a better performance on the USB and can hide latencies on the AHB.
*
* (iv) TXn min size = 16 words. (n : Transmit FIFO index)
* (v) When a TxFIFO is not used, the Configuration should be as follows:
* case 1 : n > m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txm can use the space allocated for Txn.
* case2 : n < m and Txn is not used (n,m : Transmit FIFO indexes)
* --> Txn should be configured with the minimum space of 16 words
* (vi) The FIFO is used optimally when used TxFIFOs are allocated in the top
* of the FIFO.Ex: use EP1 and EP2 as IN instead of EP1 and EP3 as IN ones.
*******************************************************************************/
#define RX_FIFO_SIZE 128
#define TX0_FIFO_SIZE 64
#define TX1_FIFO_SIZE 64
#define TX2_FIFO_SIZE 16
#define TX3_FIFO_SIZE 16
/* OTGD-FS-DEVICE IP interrupts Enable definitions */
/* Uncomment the define to enable the selected interrupt */
//#define INTR_MODEMISMATCH
#define INTR_SOFINTR
#define INTR_RXSTSQLVL /* Mandatory */
//#define INTR_NPTXFEMPTY
//#define INTR_GINNAKEFF
//#define INTR_GOUTNAKEFF
//#define INTR_ERLYSUSPEND
#define INTR_USBSUSPEND /* Mandatory */
#define INTR_USBRESET /* Mandatory */
#define INTR_ENUMDONE /* Mandatory */
//#define INTR_ISOOUTDROP
//#define INTR_EOPFRAME
//#define INTR_EPMISMATCH
#define INTR_INEPINTR /* Mandatory */
#define INTR_OUTEPINTR /* Mandatory */
//#define INTR_INCOMPLISOIN
//#define INTR_INCOMPLISOOUT
#define INTR_WKUPINTR /* Mandatory */
/* OTGD-FS-DEVICE IP interrupts subroutines */
/* Comment the define to enable the selected interrupt subroutine and replace it
by user code */
#define INTR_MODEMISMATCH_Callback NOP_Process
#define INTR_SOFINTR_Callback NOP_Process
#define INTR_RXSTSQLVL_Callback NOP_Process
#define INTR_NPTXFEMPTY_Callback NOP_Process
#define INTR_NPTXFEMPTY_Callback NOP_Process
#define INTR_GINNAKEFF_Callback NOP_Process
#define INTR_GOUTNAKEFF_Callback NOP_Process
#define INTR_ERLYSUSPEND_Callback NOP_Process
#define INTR_USBSUSPEND_Callback NOP_Process
#define INTR_USBRESET_Callback NOP_Process
#define INTR_ENUMDONE_Callback NOP_Process
#define INTR_ISOOUTDROP_Callback NOP_Process
#define INTR_EOPFRAME_Callback NOP_Process
#define INTR_EPMISMATCH_Callback NOP_Process
#define INTR_INEPINTR_Callback NOP_Process
#define INTR_OUTEPINTR_Callback NOP_Process
#define INTR_INCOMPLISOIN_Callback NOP_Process
#define INTR_INCOMPLISOOUT_Callback NOP_Process
#define INTR_WKUPINTR_Callback NOP_Process
/* Isochronous data update */
#define INTR_RXSTSQLVL_ISODU_Callback NOP_Process
/* Isochronous transfer parameters */
/* Size of a single Isochronous buffer (size of a single transfer) */
#define ISOC_BUFFER_SZE 1
/* Number of sub-buffers (number of single buffers/transfers), should be even */
#define NUM_SUB_BUFFERS 2
#endif /* STM32F10X_CL */
/* CTR service routines */
/* associated to defined endpoints */
/*#define EP1_IN_Callback NOP_Process
#define EP2_IN_Callback NOP_Process
#define EP3_IN_Callback NOP_Process
#define EP4_IN_Callback NOP_Process
#define EP5_IN_Callback NOP_Process
#define EP6_IN_Callback NOP_Process
#define EP7_IN_Callback NOP_Process
#define EP1_OUT_Callback NOP_Process
#define EP2_OUT_Callback NOP_Process
#define EP3_OUT_Callback NOP_Process
#define EP4_OUT_Callback NOP_Process
#define EP5_OUT_Callback NOP_Process
#define EP6_OUT_Callback NOP_Process
#define EP7_OUT_Callback NOP_Process*/
#endif /* __USB_CONF_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,161 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_desc.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Descriptors for Virtual Com Port Demo
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_desc.h"
/* USB Standard Device Descriptor */
const uint8_t Virtual_Com_Port_DeviceDescriptor[] =
{
0x12, /* bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x00,
0x02, /* bcdUSB = 2.00 */
0x02, /* bDeviceClass: CDC */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize0 */
0x83,
0x04, /* idVendor = 0x0483 */
0x40,
0x57, /* idProduct = 0x7540 */
0x00,
0x02, /* bcdDevice = 2.00 */
1, /* Index of string descriptor describing manufacturer */
2, /* Index of string descriptor describing product */
3, /* Index of string descriptor describing the device's serial number */
0x01 /* bNumConfigurations */
};
const uint8_t Virtual_Com_Port_ConfigDescriptor[] =
{
/*Configuation Descriptor*/
0x09, /* bLength: Configuation Descriptor size */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
VIRTUAL_COM_PORT_SIZ_CONFIG_DESC, /* wTotalLength:no of returned bytes */
0x00,
0x02, /* bNumInterfaces: 2 interface */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration: Index of string descriptor describing the configuration */
0xC0, /* bmAttributes: self powered */
0x32, /* MaxPower 0 mA */
/*Interface Descriptor*/
0x09, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoints used */
0x02, /* bInterfaceClass: Communication Interface Class */
0x02, /* bInterfaceSubClass: Abstract Control Model */
0x01, /* bInterfaceProtocol: Common AT commands */
0x00, /* iInterface: */
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
0x24, /* bDescriptorType: CS_INTERFACE */
0x00, /* bDescriptorSubtype: Header Func Desc */
0x10, /* bcdCDC: spec release number */
0x01,
/*Call Managment Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x01, /* bDescriptorSubtype: Call Management Func Desc */
0x00, /* bmCapabilities: D0+D1 */
0x01, /* bDataInterface: 1 */
/*ACM Functional Descriptor*/
0x04, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x02, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
0x24, /* bDescriptorType: CS_INTERFACE */
0x06, /* bDescriptorSubtype: Union func desc */
0x00, /* bMasterInterface: Communication class interface */
0x01, /* bSlaveInterface0: Data Class Interface */
/*Endpoint 2 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x82, /* bEndpointAddress: (IN2) */
0x03, /* bmAttributes: Interrupt */
VIRTUAL_COM_PORT_INT_SIZE, /* wMaxPacketSize: */
0x00,
0xFF, /* bInterval: */
/*Data class interface descriptor*/
0x09, /* bLength: Endpoint Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: */
0x01, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints: Two endpoints used */
0x0A, /* bInterfaceClass: CDC */
0x00, /* bInterfaceSubClass: */
0x00, /* bInterfaceProtocol: */
0x00, /* iInterface: */
/*Endpoint 3 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x03, /* bEndpointAddress: (OUT3) */
0x02, /* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */
0x00,
0x00, /* bInterval: ignore for Bulk transfer */
/*Endpoint 1 Descriptor*/
0x07, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress: (IN1) */
0x02, /* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, /* wMaxPacketSize: */
0x00,
0x00 /* bInterval */
};
/* USB String Descriptors */
const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID] =
{
VIRTUAL_COM_PORT_SIZ_STRING_LANGID,
USB_STRING_DESCRIPTOR_TYPE,
0x09,
0x04 /* LangID = 0x0409: U.S. English */
};
const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR] =
{
VIRTUAL_COM_PORT_SIZ_STRING_VENDOR, /* Size of Vendor string */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/
/* Manufacturer: "STMicroelectronics" */
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
'c', 0, 's', 0
};
const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT] =
{
VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
/* Product name: "STM32 Virtual COM Port" */
'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'V', 0, 'i', 0,
'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0,
'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0, ' ', 0, ' ', 0
};
uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL] =
{
VIRTUAL_COM_PORT_SIZ_STRING_SERIAL, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
};
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,53 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_desc.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Descriptor Header for Virtual COM Port Device
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DESC_H
#define __USB_DESC_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported define -----------------------------------------------------------*/
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
#define USB_STRING_DESCRIPTOR_TYPE 0x03
#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
#define VIRTUAL_COM_PORT_DATA_SIZE 64
#define VIRTUAL_COM_PORT_INT_SIZE 8
#define VIRTUAL_COM_PORT_SIZ_DEVICE_DESC 18
#define VIRTUAL_COM_PORT_SIZ_CONFIG_DESC 67
#define VIRTUAL_COM_PORT_SIZ_STRING_LANGID 4
#define VIRTUAL_COM_PORT_SIZ_STRING_VENDOR 38
#define VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT 50
#define VIRTUAL_COM_PORT_SIZ_STRING_SERIAL 26
#define STANDARD_ENDPOINT_DESC_SIZE 0x09
/* Exported functions ------------------------------------------------------- */
extern const uint8_t Virtual_Com_Port_DeviceDescriptor[VIRTUAL_COM_PORT_SIZ_DEVICE_DESC];
extern const uint8_t Virtual_Com_Port_ConfigDescriptor[VIRTUAL_COM_PORT_SIZ_CONFIG_DESC];
extern const uint8_t Virtual_Com_Port_StringLangID[VIRTUAL_COM_PORT_SIZ_STRING_LANGID];
extern const uint8_t Virtual_Com_Port_StringVendor[VIRTUAL_COM_PORT_SIZ_STRING_VENDOR];
extern const uint8_t Virtual_Com_Port_StringProduct[VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT];
extern uint8_t Virtual_Com_Port_StringSerial[VIRTUAL_COM_PORT_SIZ_STRING_SERIAL];
#endif /* __USB_DESC_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,67 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_endp.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Endpoint routines
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_desc.h"
#include "usb_mem.h"
#include "hw_config.h"
#include "usb_istr.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t buffer_out[VIRTUAL_COM_PORT_DATA_SIZE];
uint8_t buffer_in[VIRTUAL_COM_PORT_DATA_SIZE];
__IO uint32_t count_out = 0;
uint32_t count_in = 0;
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : EP1_IN_Callback
* Description :
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void EP3_IN_Callback(void)
{
count_in = 0;
}
/*******************************************************************************
* Function Name : EP3_IN_Callback
* Description :
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void EP5_OUT_Callback(void)
{
/* Get the received data buffer and update the counter */
count_out = USB_SIL_Read(EP5_OUT, buffer_out);
#ifndef STM32F10X_CL
/* Enable the receive of data on EP3 */
SetEPRxValid(ENDP3);
#endif /* STM32F10X_CL */
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,419 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_istr.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : ISTR events interrupt service routines
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_prop.h"
#include "usb_pwr.h"
#include "usb_istr.h"
/* function prototypes Automatically built defining related macros */
void NOP_Proc(void) {
}
#define WEAK __attribute__ ((weak))
void WEAK EP1_IN_Callback(void);
void WEAK EP2_IN_Callback(void);
void WEAK EP3_IN_Callback(void);
void WEAK EP4_IN_Callback(void);
void WEAK EP5_IN_Callback(void);
void WEAK EP6_IN_Callback(void);
void WEAK EP7_IN_Callback(void);
void WEAK EP1_OUT_Callback(void);
void WEAK EP2_OUT_Callback(void);
void WEAK EP3_OUT_Callback(void);
void WEAK EP4_OUT_Callback(void);
void WEAK EP5_OUT_Callback(void);
void WEAK EP6_OUT_Callback(void);
void WEAK EP7_OUT_Callback(void);
#pragma weak EP1_IN_Callback = NOP_Proc
#pragma weak EP2_IN_Callback = NOP_Proc
#pragma weak EP3_IN_Callback = NOP_Proc
#pragma weak EP4_IN_Callback = NOP_Proc
#pragma weak EP5_IN_Callback = NOP_Proc
#pragma weak EP6_IN_Callback = NOP_Proc
#pragma weak EP7_IN_Callback = NOP_Proc
#pragma weak EP1_OUT_Callback = NOP_Proc
#pragma weak EP2_OUT_Callback = NOP_Proc
#pragma weak EP3_OUT_Callback = NOP_Proc
#pragma weak EP4_OUT_Callback = NOP_Proc
#pragma weak EP5_OUT_Callback = NOP_Proc
#pragma weak EP6_OUT_Callback = NOP_Proc
#pragma weak EP7_OUT_Callback = NOP_Proc
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t wIstr; /* ISTR register last read value */
__IO uint8_t bIntPackSOF = 0; /* SOFs received between 2 consecutive packets */
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* function pointers to non-control endpoints service routines */
void (*const pEpInt_IN[7])(void) =
{
EP1_IN_Callback,
EP2_IN_Callback,
EP3_IN_Callback,
EP4_IN_Callback,
EP5_IN_Callback,
EP6_IN_Callback,
EP7_IN_Callback,
};
void (*const pEpInt_OUT[7])(void) =
{
EP1_OUT_Callback,
EP2_OUT_Callback,
EP3_OUT_Callback,
EP4_OUT_Callback,
EP5_OUT_Callback,
EP6_OUT_Callback,
EP7_OUT_Callback,
};
#ifndef STM32F10X_CL
/*******************************************************************************
* Function Name : USB_Istr
* Description : STR events interrupt service routine
* Input :
* Output :
* Return :
*******************************************************************************/
void USB_Istr(void)
{
wIstr = _GetISTR();
#if (IMR_MSK & ISTR_CTR)
if (wIstr & ISTR_CTR & wInterrupt_Mask)
{
/* servicing of the endpoint correct transfer interrupt */
/* clear of the CTR flag into the sub */
CTR_LP();
#ifdef CTR_CALLBACK
CTR_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_RESET)
if (wIstr & ISTR_RESET & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_RESET);
Device_Property.Reset();
#ifdef RESET_CALLBACK
RESET_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_DOVR)
if (wIstr & ISTR_DOVR & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_DOVR);
#ifdef DOVR_CALLBACK
DOVR_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ERR)
if (wIstr & ISTR_ERR & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_ERR);
#ifdef ERR_CALLBACK
ERR_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_WKUP)
if (wIstr & ISTR_WKUP & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_WKUP);
Resume(RESUME_EXTERNAL);
#ifdef WKUP_CALLBACK
WKUP_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SUSP)
if (wIstr & ISTR_SUSP & wInterrupt_Mask)
{
/* check if SUSPEND is possible */
if (fSuspendEnabled)
{
Suspend();
}
else
{
/* if not possible then resume after xx ms */
Resume(RESUME_LATER);
}
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
_SetISTR((uint16_t)CLR_SUSP);
#ifdef SUSP_CALLBACK
SUSP_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_SOF)
if (wIstr & ISTR_SOF & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_SOF);
bIntPackSOF++;
#ifdef SOF_CALLBACK
SOF_Callback();
#endif
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (IMR_MSK & ISTR_ESOF)
if (wIstr & ISTR_ESOF & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_ESOF);
/* resume handling timing is made with ESOFs */
Resume(RESUME_ESOF); /* request without change of the machine state */
#ifdef ESOF_CALLBACK
ESOF_Callback();
#endif
}
#endif
} /* USB_Istr */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#else /* STM32F10X_CL */
/*******************************************************************************
* Function Name : STM32_PCD_OTG_ISR_Handler
* Description : Handles all USB Device Interrupts
* Input : None
* Output : None
* Return : status
*******************************************************************************/
u32 STM32_PCD_OTG_ISR_Handler (void)
{
USB_OTG_int_sts_data gintr_status;
u32 retval = 0;
if (IsDeviceMode()) /* ensure that we are in device mode */
{
gintr_status.d32 = OTGD_FS_ReadCoreItr();
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* If there is no interrupt pending exit the interrupt routine */
if (!gintr_status.d32)
{
return 0;
}
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Early Suspend interrupt */
#ifdef INTR_ERLYSUSPEND
if (gintr_status.b.erlysuspend)
{
retval |= OTGD_FS_Handle_EarlySuspend_ISR();
}
#endif /* INTR_ERLYSUSPEND */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* End of Periodic Frame interrupt */
#ifdef INTR_EOPFRAME
if (gintr_status.b.eopframe)
{
retval |= OTGD_FS_Handle_EOPF_ISR();
}
#endif /* INTR_EOPFRAME */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Non Periodic Tx FIFO Emty interrupt */
#ifdef INTR_NPTXFEMPTY
if (gintr_status.b.nptxfempty)
{
retval |= OTGD_FS_Handle_NPTxFE_ISR();
}
#endif /* INTR_NPTXFEMPTY */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Wakeup or RemoteWakeup interrupt */
#ifdef INTR_WKUPINTR
if (gintr_status.b.wkupintr)
{
retval |= OTGD_FS_Handle_Wakeup_ISR();
}
#endif /* INTR_WKUPINTR */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Suspend interrupt */
#ifdef INTR_USBSUSPEND
if (gintr_status.b.usbsuspend)
{
/* check if SUSPEND is possible */
if (fSuspendEnabled)
{
Suspend();
}
else
{
/* if not possible then resume after xx ms */
Resume(RESUME_LATER); /* This case shouldn't happen in OTG Device mode because
there's no ESOF interrupt to increment the ResumeS.bESOFcnt in the Resume state machine */
}
retval |= OTGD_FS_Handle_USBSuspend_ISR();
}
#endif /* INTR_USBSUSPEND */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Start of Frame interrupt */
#ifdef INTR_SOFINTR
if (gintr_status.b.sofintr)
{
/* Update the frame number variable */
bIntPackSOF++;
retval |= OTGD_FS_Handle_Sof_ISR();
}
#endif /* INTR_SOFINTR */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Receive FIFO Queue Status Level interrupt */
#ifdef INTR_RXSTSQLVL
if (gintr_status.b.rxstsqlvl)
{
retval |= OTGD_FS_Handle_RxStatusQueueLevel_ISR();
}
#endif /* INTR_RXSTSQLVL */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Enumeration Done interrupt */
#ifdef INTR_ENUMDONE
if (gintr_status.b.enumdone)
{
retval |= OTGD_FS_Handle_EnumDone_ISR();
}
#endif /* INTR_ENUMDONE */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Reset interrutp */
#ifdef INTR_USBRESET
if (gintr_status.b.usbreset)
{
retval |= OTGD_FS_Handle_UsbReset_ISR();
}
#endif /* INTR_USBRESET */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* IN Endpoint interrupt */
#ifdef INTR_INEPINTR
if (gintr_status.b.inepint)
{
retval |= OTGD_FS_Handle_InEP_ISR();
}
#endif /* INTR_INEPINTR */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* OUT Endpoint interrupt */
#ifdef INTR_OUTEPINTR
if (gintr_status.b.outepintr)
{
retval |= OTGD_FS_Handle_OutEP_ISR();
}
#endif /* INTR_OUTEPINTR */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Mode Mismatch interrupt */
#ifdef INTR_MODEMISMATCH
if (gintr_status.b.modemismatch)
{
retval |= OTGD_FS_Handle_ModeMismatch_ISR();
}
#endif /* INTR_MODEMISMATCH */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Global IN Endpoints NAK Effective interrupt */
#ifdef INTR_GINNAKEFF
if (gintr_status.b.ginnakeff)
{
retval |= OTGD_FS_Handle_GInNakEff_ISR();
}
#endif /* INTR_GINNAKEFF */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Global OUT Endpoints NAK effective interrupt */
#ifdef INTR_GOUTNAKEFF
if (gintr_status.b.goutnakeff)
{
retval |= OTGD_FS_Handle_GOutNakEff_ISR();
}
#endif /* INTR_GOUTNAKEFF */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Isochrounous Out packet Dropped interrupt */
#ifdef INTR_ISOOUTDROP
if (gintr_status.b.isooutdrop)
{
retval |= OTGD_FS_Handle_IsoOutDrop_ISR();
}
#endif /* INTR_ISOOUTDROP */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Endpoint Mismatch error interrupt */
#ifdef INTR_EPMISMATCH
if (gintr_status.b.epmismatch)
{
retval |= OTGD_FS_Handle_EPMismatch_ISR();
}
#endif /* INTR_EPMISMATCH */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Incomplete Isochrous IN tranfer error interrupt */
#ifdef INTR_INCOMPLISOIN
if (gintr_status.b.incomplisoin)
{
retval |= OTGD_FS_Handle_IncomplIsoIn_ISR();
}
#endif /* INTR_INCOMPLISOIN */
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
/* Incomplete Isochrous OUT tranfer error interrupt */
#ifdef INTR_INCOMPLISOOUT
if (gintr_status.b.outepintr)
{
retval |= OTGD_FS_Handle_IncomplIsoOut_ISR();
}
#endif /* INTR_INCOMPLISOOUT */
}
return retval;
}
#endif /* STM32F10X_CL */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,104 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_istr.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : This file includes the peripherals header files in the
* user application.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_ISTR_H
#define __USB_ISTR_H
/* Includes ------------------------------------------------------------------*/
#include "usb_conf.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#ifndef STM32F10X_CL
void USB_Istr(void);
#else /* STM32F10X_CL */
u32 STM32_PCD_OTG_ISR_Handler(void);
#endif /* STM32F10X_CL */
#ifndef STM32F10X_CL
#ifdef CTR_CALLBACK
void CTR_Callback(void);
#endif
#ifdef DOVR_CALLBACK
void DOVR_Callback(void);
#endif
#ifdef ERR_CALLBACK
void ERR_Callback(void);
#endif
#ifdef WKUP_CALLBACK
void WKUP_Callback(void);
#endif
#ifdef SUSP_CALLBACK
void SUSP_Callback(void);
#endif
#ifdef RESET_CALLBACK
void RESET_Callback(void);
#endif
#ifdef SOF_CALLBACK
void SOF_Callback(void);
#endif
#ifdef ESOF_CALLBACK
void ESOF_Callback(void);
#endif
#else /* STM32F10X_CL */
/* Interrupt subroutines user callbacks prototypes.
These callbacks are called into the respective interrupt sunroutine functinos
and can be tailored for various user application purposes.
Note: Make sure that the correspondant interrupt is enabled through the
definition in usb_conf.h file */
void INTR_MODEMISMATCH_Callback(void);
void INTR_SOFINTR_Callback(void);
void INTR_RXSTSQLVL_Callback(void);
void INTR_NPTXFEMPTY_Callback(void);
void INTR_GINNAKEFF_Callback(void);
void INTR_GOUTNAKEFF_Callback(void);
void INTR_ERLYSUSPEND_Callback(void);
void INTR_USBSUSPEND_Callback(void);
void INTR_USBRESET_Callback(void);
void INTR_ENUMDONE_Callback(void);
void INTR_ISOOUTDROP_Callback(void);
void INTR_EOPFRAME_Callback(void);
void INTR_EPMISMATCH_Callback(void);
void INTR_INEPINTR_Callback(void);
void INTR_OUTEPINTR_Callback(void);
void INTR_INCOMPLISOIN_Callback(void);
void INTR_INCOMPLISOOUT_Callback(void);
void INTR_WKUPINTR_Callback(void);
/* Isochronous data update */
void INTR_RXSTSQLVL_ISODU_Callback(void);
#endif /* STM32F10X_CL */
#endif /*__USB_ISTR_H*/
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,419 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_prop.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : All processing related to Virtual Com Port Demo
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
#include "usb_conf.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "hw_config.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint8_t Request = 0;
LINE_CODING linecoding =
{
115200, /* baud rate*/
0x00, /* stop bits-1*/
0x00, /* parity - none*/
0x08 /* no. of bits 8*/
};
/* -------------------------------------------------------------------------- */
/* Structures initializations */
/* -------------------------------------------------------------------------- */
DEVICE Device_Table =
{
EP_NUM,
1
};
DEVICE_PROP Device_Property =
{
Virtual_Com_Port_init,
Virtual_Com_Port_Reset,
Virtual_Com_Port_Status_In,
Virtual_Com_Port_Status_Out,
Virtual_Com_Port_Data_Setup,
Virtual_Com_Port_NoData_Setup,
Virtual_Com_Port_Get_Interface_Setting,
Virtual_Com_Port_GetDeviceDescriptor,
Virtual_Com_Port_GetConfigDescriptor,
Virtual_Com_Port_GetStringDescriptor,
0,
0x40 /*MAX PACKET SIZE*/
};
USER_STANDARD_REQUESTS User_Standard_Requests =
{
Virtual_Com_Port_GetConfiguration,
Virtual_Com_Port_SetConfiguration,
Virtual_Com_Port_GetInterface,
Virtual_Com_Port_SetInterface,
Virtual_Com_Port_GetStatus,
Virtual_Com_Port_ClearFeature,
Virtual_Com_Port_SetEndPointFeature,
Virtual_Com_Port_SetDeviceFeature,
Virtual_Com_Port_SetDeviceAddress
};
ONE_DESCRIPTOR Device_Descriptor =
{
(uint8_t*)Virtual_Com_Port_DeviceDescriptor,
VIRTUAL_COM_PORT_SIZ_DEVICE_DESC
};
ONE_DESCRIPTOR Config_Descriptor =
{
(uint8_t*)Virtual_Com_Port_ConfigDescriptor,
VIRTUAL_COM_PORT_SIZ_CONFIG_DESC
};
ONE_DESCRIPTOR String_Descriptor[4] =
{
{(uint8_t*)Virtual_Com_Port_StringLangID, VIRTUAL_COM_PORT_SIZ_STRING_LANGID},
{(uint8_t*)Virtual_Com_Port_StringVendor, VIRTUAL_COM_PORT_SIZ_STRING_VENDOR},
{(uint8_t*)Virtual_Com_Port_StringProduct, VIRTUAL_COM_PORT_SIZ_STRING_PRODUCT},
{(uint8_t*)Virtual_Com_Port_StringSerial, VIRTUAL_COM_PORT_SIZ_STRING_SERIAL}
};
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Extern function prototypes ------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : Virtual_Com_Port_init.
* Description : Virtual COM Port Mouse init routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Virtual_Com_Port_init(void)
{
/* Update the serial number string descriptor with the data from the unique
ID*/
Get_SerialNum();
pInformation->Current_Configuration = 0;
/* Connect the device */
PowerOn();
/* Perform basic device initialization operations */
USB_SIL_Init();
/* configure the USART to the default settings */
//USART_Config_Default();
bDeviceState = UNCONNECTED;
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_Reset
* Description : Virtual_Com_Port Mouse reset routine
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Virtual_Com_Port_Reset(void)
{
/* Set Virtual_Com_Port DEVICE as not configured */
pInformation->Current_Configuration = 0;
/* Current Feature initialization */
pInformation->Current_Feature = Virtual_Com_Port_ConfigDescriptor[7];
/* Set Virtual_Com_Port DEVICE with the default Interface*/
pInformation->Current_Interface = 0;
#ifdef STM32F10X_CL
/* EP0 is already configured by USB_SIL_Init() function */
/* Init EP1 IN as Bulk endpoint */
OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_BULK, VIRTUAL_COM_PORT_DATA_SIZE);
/* Init EP2 IN as Interrupt endpoint */
OTG_DEV_EP_Init(EP2_IN, OTG_DEV_EP_TYPE_INT, VIRTUAL_COM_PORT_INT_SIZE);
/* Init EP3 OUT as Bulk endpoint */
OTG_DEV_EP_Init(EP3_OUT, OTG_DEV_EP_TYPE_BULK, VIRTUAL_COM_PORT_DATA_SIZE);
#else
SetBTABLE(BTABLE_ADDRESS);
/* Initialize Endpoint 0 */
SetEPType(ENDP0, EP_CONTROL);
SetEPTxStatus(ENDP0, EP_TX_STALL);
SetEPRxAddr(ENDP0, ENDP0_RXADDR);
SetEPTxAddr(ENDP0, ENDP0_TXADDR);
Clear_Status_Out(ENDP0);
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
SetEPRxValid(ENDP0);
/* Initialize Endpoint 1 */
SetEPType(ENDP1, EP_BULK);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxStatus(ENDP1, EP_RX_DIS);
/* Initialize Endpoint 2 */
SetEPType(ENDP2, EP_INTERRUPT);
SetEPTxAddr(ENDP2, ENDP2_TXADDR);
SetEPRxStatus(ENDP2, EP_RX_DIS);
SetEPTxStatus(ENDP2, EP_TX_NAK);
/* Initialize Endpoint 3 */
SetEPType(ENDP3, EP_BULK);
SetEPRxAddr(ENDP3, ENDP3_RXADDR);
SetEPRxCount(ENDP3, VIRTUAL_COM_PORT_DATA_SIZE);
SetEPRxStatus(ENDP3, EP_RX_VALID);
SetEPTxStatus(ENDP3, EP_TX_DIS);
/* Set this device to response on default address */
SetDeviceAddress(0);
#endif /* STM32F10X_CL */
bDeviceState = ATTACHED;
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_SetConfiguration.
* Description : Udpade the device state to configured.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Virtual_Com_Port_SetConfiguration(void)
{
DEVICE_INFO *pInfo = &Device_Info;
if (pInfo->Current_Configuration != 0)
{
/* Device configured */
bDeviceState = CONFIGURED;
}
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_SetConfiguration.
* Description : Udpade the device state to addressed.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Virtual_Com_Port_SetDeviceAddress (void)
{
bDeviceState = ADDRESSED;
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_Status_In.
* Description : Virtual COM Port Status In Routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Virtual_Com_Port_Status_In(void)
{
if (Request == SET_LINE_CODING)
{
//USART_Config();
Request = 0;
}
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_Status_Out
* Description : Virtual COM Port Status OUT Routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void Virtual_Com_Port_Status_Out(void)
{}
/*******************************************************************************
* Function Name : Virtual_Com_Port_Data_Setup
* Description : handle the data class specific requests
* Input : Request Nb.
* Output : None.
* Return : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
RESULT Virtual_Com_Port_Data_Setup(uint8_t RequestNo)
{
uint8_t *(*CopyRoutine)(uint16_t);
CopyRoutine = NULL;
if (RequestNo == GET_LINE_CODING)
{
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
CopyRoutine = Virtual_Com_Port_GetLineCoding;
}
}
else if (RequestNo == SET_LINE_CODING)
{
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
CopyRoutine = Virtual_Com_Port_SetLineCoding;
}
Request = SET_LINE_CODING;
}
if (CopyRoutine == NULL)
{
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_NoData_Setup.
* Description : handle the no data class specific requests.
* Input : Request Nb.
* Output : None.
* Return : USB_UNSUPPORT or USB_SUCCESS.
*******************************************************************************/
RESULT Virtual_Com_Port_NoData_Setup(uint8_t RequestNo)
{
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
{
if (RequestNo == SET_COMM_FEATURE)
{
return USB_SUCCESS;
}
else if (RequestNo == SET_CONTROL_LINE_STATE)
{
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_GetDeviceDescriptor.
* Description : Gets the device descriptor.
* Input : Length.
* Output : None.
* Return : The address of the device descriptor.
*******************************************************************************/
uint8_t *Virtual_Com_Port_GetDeviceDescriptor(uint16_t Length)
{
return Standard_GetDescriptorData(Length, &Device_Descriptor);
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_GetConfigDescriptor.
* Description : get the configuration descriptor.
* Input : Length.
* Output : None.
* Return : The address of the configuration descriptor.
*******************************************************************************/
uint8_t *Virtual_Com_Port_GetConfigDescriptor(uint16_t Length)
{
return Standard_GetDescriptorData(Length, &Config_Descriptor);
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_GetStringDescriptor
* Description : Gets the string descriptors according to the needed index
* Input : Length.
* Output : None.
* Return : The address of the string descriptors.
*******************************************************************************/
uint8_t *Virtual_Com_Port_GetStringDescriptor(uint16_t Length)
{
uint8_t wValue0 = pInformation->USBwValue0;
if (wValue0 > 4)
{
return NULL;
}
else
{
return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
}
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_Get_Interface_Setting.
* Description : test the interface and the alternate setting according to the
* supported one.
* Input1 : uint8_t: Interface : interface number.
* Input2 : uint8_t: AlternateSetting : Alternate Setting number.
* Output : None.
* Return : The address of the string descriptors.
*******************************************************************************/
RESULT Virtual_Com_Port_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting)
{
if (AlternateSetting > 0)
{
return USB_UNSUPPORT;
}
else if (Interface > 1)
{
return USB_UNSUPPORT;
}
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_GetLineCoding.
* Description : send the linecoding structure to the PC host.
* Input : Length.
* Output : None.
* Return : Inecoding structure base address.
*******************************************************************************/
uint8_t *Virtual_Com_Port_GetLineCoding(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
return NULL;
}
return(uint8_t *)&linecoding;
}
/*******************************************************************************
* Function Name : Virtual_Com_Port_SetLineCoding.
* Description : Set the linecoding structure fields.
* Input : Length.
* Output : None.
* Return : Linecoding structure base address.
*******************************************************************************/
uint8_t *Virtual_Com_Port_SetLineCoding(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
return NULL;
}
return(uint8_t *)&linecoding;
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,74 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_prop.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : All processing related to Virtual COM Port Demo (Endpoint 0)
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __usb_prop_H
#define __usb_prop_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef struct
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
}LINE_CODING;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported define -----------------------------------------------------------*/
#define Virtual_Com_Port_GetConfiguration NOP_Process
//#define Virtual_Com_Port_SetConfiguration NOP_Process
#define Virtual_Com_Port_GetInterface NOP_Process
#define Virtual_Com_Port_SetInterface NOP_Process
#define Virtual_Com_Port_GetStatus NOP_Process
#define Virtual_Com_Port_ClearFeature NOP_Process
#define Virtual_Com_Port_SetEndPointFeature NOP_Process
#define Virtual_Com_Port_SetDeviceFeature NOP_Process
//#define Virtual_Com_Port_SetDeviceAddress NOP_Process
#define SEND_ENCAPSULATED_COMMAND 0x00
#define GET_ENCAPSULATED_RESPONSE 0x01
#define SET_COMM_FEATURE 0x02
#define GET_COMM_FEATURE 0x03
#define CLEAR_COMM_FEATURE 0x04
#define SET_LINE_CODING 0x20
#define GET_LINE_CODING 0x21
#define SET_CONTROL_LINE_STATE 0x22
#define SEND_BREAK 0x23
/* Exported functions ------------------------------------------------------- */
void Virtual_Com_Port_init(void);
void Virtual_Com_Port_Reset(void);
void Virtual_Com_Port_SetConfiguration(void);
void Virtual_Com_Port_SetDeviceAddress (void);
void Virtual_Com_Port_Status_In (void);
void Virtual_Com_Port_Status_Out (void);
RESULT Virtual_Com_Port_Data_Setup(uint8_t);
RESULT Virtual_Com_Port_NoData_Setup(uint8_t);
RESULT Virtual_Com_Port_Get_Interface_Setting(uint8_t Interface, uint8_t AlternateSetting);
uint8_t *Virtual_Com_Port_GetDeviceDescriptor(uint16_t );
uint8_t *Virtual_Com_Port_GetConfigDescriptor(uint16_t);
uint8_t *Virtual_Com_Port_GetStringDescriptor(uint16_t);
uint8_t *Virtual_Com_Port_GetLineCoding(uint16_t Length);
uint8_t *Virtual_Com_Port_SetLineCoding(uint16_t Length);
#endif /* __usb_prop_H */
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,251 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_pwr.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Connection/disconnection & power management
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "usb_lib.h"
#include "usb_conf.h"
#include "usb_pwr.h"
#include "hw_config.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint32_t bDeviceState = UNCONNECTED; /* USB device status */
__IO bool fSuspendEnabled = TRUE; /* true when suspend is possible */
struct
{
__IO RESUME_STATE eState;
__IO uint8_t bESOFcnt;
}ResumeS;
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Extern function prototypes ------------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : PowerOn
* Description :
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
RESULT PowerOn(void)
{
#ifndef STM32F10X_CL
uint16_t wRegVal;
/*** cable plugged-in ? ***/
USB_Cable_Config(ENABLE);
/*** CNTR_PWDN = 0 ***/
wRegVal = CNTR_FRES;
_SetCNTR(wRegVal);
/*** CNTR_FRES = 0 ***/
wInterrupt_Mask = 0;
_SetCNTR(wInterrupt_Mask);
/*** Clear pending interrupts ***/
_SetISTR(0);
/*** Set interrupt mask ***/
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
_SetCNTR(wInterrupt_Mask);
#endif /* STM32F10X_CL */
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : PowerOff
* Description : handles switch-off conditions
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
RESULT PowerOff()
{
#ifndef STM32F10X_CL
/* disable all ints and force USB reset */
_SetCNTR(CNTR_FRES);
/* clear interrupt status register */
_SetISTR(0);
/* Disable the Pull-Up*/
USB_Cable_Config(DISABLE);
/* switch-off device */
_SetCNTR(CNTR_FRES + CNTR_PDWN);
#endif /* STM32F10X_CL */
/* sw variables reset */
/* ... */
return USB_SUCCESS;
}
/*******************************************************************************
* Function Name : Suspend
* Description : sets suspend mode operating conditions
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
void Suspend(void)
{
#ifndef STM32F10X_CL
uint16_t wCNTR;
/* suspend preparation */
/* ... */
/* macrocell enters suspend mode */
wCNTR = _GetCNTR();
wCNTR |= CNTR_FSUSP;
_SetCNTR(wCNTR);
#endif /* STM32F10X_CL */
/* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
/* power reduction */
/* ... on connected devices */
#ifndef STM32F10X_CL
/* force low-power mode in the macrocell */
wCNTR = _GetCNTR();
wCNTR |= CNTR_LPMODE;
_SetCNTR(wCNTR);
#endif /* STM32F10X_CL */
/* switch-off the clocks */
/* ... */
Enter_LowPowerMode();
}
/*******************************************************************************
* Function Name : Resume_Init
* Description : Handles wake-up restoring normal operations
* Input : None.
* Output : None.
* Return : USB_SUCCESS.
*******************************************************************************/
void Resume_Init(void)
{
#ifndef STM32F10X_CL
uint16_t wCNTR;
#endif /* STM32F10X_CL */
/* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
/* restart the clocks */
/* ... */
#ifndef STM32F10X_CL
/* CNTR_LPMODE = 0 */
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_LPMODE);
_SetCNTR(wCNTR);
#endif /* STM32F10X_CL */
/* restore full power */
/* ... on connected devices */
Leave_LowPowerMode();
#ifndef STM32F10X_CL
/* reset FSUSP bit */
_SetCNTR(IMR_MSK);
#endif /* STM32F10X_CL */
/* reverse suspend preparation */
/* ... */
}
/*******************************************************************************
* Function Name : Resume
* Description : This is the state machine handling resume operations and
* timing sequence. The control is based on the Resume structure
* variables and on the ESOF interrupt calling this subroutine
* without changing machine state.
* Input : a state machine value (RESUME_STATE)
* RESUME_ESOF doesn't change ResumeS.eState allowing
* decrementing of the ESOF counter in different states.
* Output : None.
* Return : None.
*******************************************************************************/
void Resume(RESUME_STATE eResumeSetVal)
{
#ifndef STM32F10X_CL
uint16_t wCNTR;
#endif /* STM32F10X_CL */
if (eResumeSetVal != RESUME_ESOF)
ResumeS.eState = eResumeSetVal;
switch (ResumeS.eState)
{
case RESUME_EXTERNAL:
Resume_Init();
ResumeS.eState = RESUME_OFF;
break;
case RESUME_INTERNAL:
Resume_Init();
ResumeS.eState = RESUME_START;
break;
case RESUME_LATER:
ResumeS.bESOFcnt = 2;
ResumeS.eState = RESUME_WAIT;
break;
case RESUME_WAIT:
ResumeS.bESOFcnt--;
if (ResumeS.bESOFcnt == 0)
ResumeS.eState = RESUME_START;
break;
case RESUME_START:
#ifdef STM32F10X_CL
OTGD_FS_Dev_SetRemoteWakeup();
#else
wCNTR = _GetCNTR();
wCNTR |= CNTR_RESUME;
_SetCNTR(wCNTR);
#endif /* STM32F10X_CL */
ResumeS.eState = RESUME_ON;
ResumeS.bESOFcnt = 10;
break;
case RESUME_ON:
#ifndef STM32F10X_CL
ResumeS.bESOFcnt--;
if (ResumeS.bESOFcnt == 0)
{
#endif /* STM32F10X_CL */
#ifdef STM32F10X_CL
OTGD_FS_Dev_ResetRemoteWakeup();
#else
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_RESUME);
_SetCNTR(wCNTR);
#endif /* STM32F10X_CL */
ResumeS.eState = RESUME_OFF;
#ifndef STM32F10X_CL
}
#endif /* STM32F10X_CL */
break;
case RESUME_OFF:
case RESUME_ESOF:
default:
ResumeS.eState = RESUME_OFF;
break;
}
}
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

View File

@@ -1,59 +0,0 @@
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_pwr.h
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : Connection/disconnection & power management header
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_PWR_H
#define __USB_PWR_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _RESUME_STATE
{
RESUME_EXTERNAL,
RESUME_INTERNAL,
RESUME_LATER,
RESUME_WAIT,
RESUME_START,
RESUME_ON,
RESUME_OFF,
RESUME_ESOF
} RESUME_STATE;
typedef enum _DEVICE_STATE
{
UNCONNECTED,
ATTACHED,
POWERED,
SUSPENDED,
ADDRESSED,
CONFIGURED
} DEVICE_STATE;
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void Suspend(void);
void Resume_Init(void);
void Resume(RESUME_STATE eResumeSetVal);
RESULT PowerOn(void);
RESULT PowerOff(void);
/* External variables --------------------------------------------------------*/
extern __IO uint32_t bDeviceState; /* USB device status */
extern __IO bool fSuspendEnabled; /* true when suspend is possible */
#endif /*__USB_PWR_H*/
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/

107
boards/FST_01/board.c Normal file
View File

@@ -0,0 +1,107 @@
#include "config.h"
#include "ch.h"
#include "hal.h"
#include "../common/hwinit.c"
void
hwinit0 (void)
{
hwinit0_common ();
}
void
hwinit1 (void)
{
hwinit1_common ();
#if defined(PINPAD_CIR_SUPPORT)
/* PA0/TIM2_CH1 = 1 (pull up) */
/* PA1/TIM2_CH2 = 0 (pull down) */
/* PA2/TIM2_CH3 <= Vout of CIR receiver module */
/* EXTI2 <= PA2 */
AFIO->EXTICR[0] = AFIO_EXTICR1_EXTI2_PA;
EXTI->IMR = 0;
EXTI->FTSR = EXTI_FTSR_TR2;
NVICEnableVector(EXTI2_IRQn,
CORTEX_PRIORITY_MASK(CORTEX_MINIMUM_PRIORITY));
/* TIM2 */
RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
RCC->APB1RSTR = RCC_APB1RSTR_TIM2RST;
RCC->APB1RSTR = 0;
NVICEnableVector(TIM2_IRQn,
CORTEX_PRIORITY_MASK(CORTEX_MINIMUM_PRIORITY));
TIM2->CR1 = TIM_CR1_URS | TIM_CR1_ARPE;
TIM2->CR2 = TIM_CR2_TI1S;
TIM2->SMCR = TIM_SMCR_TS_0 | TIM_SMCR_TS_2 | TIM_SMCR_SMS_2;
TIM2->DIER = 0; /* Disable interrupt for now */
TIM2->CCMR1 = TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_3
| TIM_CCMR1_CC2S_1 | TIM_CCMR1_IC2F_0 | TIM_CCMR1_IC2F_3;
TIM2->CCMR2 = 0;
TIM2->CCER = TIM_CCER_CC1E | TIM_CCER_CC2E | TIM_CCER_CC2P;
TIM2->PSC = 72 - 1; /* 1 MHz */
TIM2->ARR = 18000; /* 18 ms */
/* Generate UEV to upload PSC and ARR */
TIM2->EGR = TIM_EGR_UG;
#endif
}
void
USB_Cable_Config (int NewState)
{
if (NewState != DISABLE)
palSetPad (IOPORT1, GPIOA_USB_ENABLE);
else
palClearPad (IOPORT1, GPIOA_USB_ENABLE);
}
void
set_led (int value)
{
if (value)
palSetPad (IOPORT2, GPIOB_LED);
else
palClearPad (IOPORT2, GPIOB_LED);
}
#if defined(PINPAD_CIR_SUPPORT)
void
cir_ext_disable (void)
{
EXTI->PR = EXTI_PR_PR2;
EXTI->IMR &= ~EXTI_IMR_MR2;
}
void
cir_ext_enable (void)
{
EXTI->IMR |= EXTI_IMR_MR2;
}
extern void cir_ext_interrupt (void);
extern void cir_timer_interrupt (void);
CH_IRQ_HANDLER (EXTI2_IRQHandler)
{
CH_IRQ_PROLOGUE ();
chSysLockFromIsr ();
cir_ext_interrupt ();
chSysUnlockFromIsr ();
CH_IRQ_EPILOGUE ();
}
CH_IRQ_HANDLER (TIM2_IRQHandler)
{
CH_IRQ_PROLOGUE();
chSysLockFromIsr();
cir_timer_interrupt ();
chSysUnlockFromIsr();
CH_IRQ_EPILOGUE();
}
#endif

138
boards/FST_01/board.h Normal file
View File

@@ -0,0 +1,138 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/*
* Setup for the FST-01 board.
*/
/*
* Board identifier.
*/
#define BOARD_FST_01
#define BOARD_NAME "FST-01"
/*
* Board frequencies.
*/
#define STM32_LSECLK 32768
#define STM32_HSECLK 12000000
/*
* MCU type, this macro is used by both the ST library and the ChibiOS/RT
* native STM32 HAL.
*/
#define STM32F10X_MD
#define CPU_WITH_NO_GPIOE 1
/*
* IO pins assignments.
*/
#define GPIOB_LED 0
#define GPIOA_USB_ENABLE 10
#define GPIOA_SPI1NSS 4
/*
* Timer assignment for CIR
*/
#define TIMx TIM2
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
*
* The digits have the following meaning:
* 0 - Analog input.
* 1 - Push Pull output 10MHz.
* 2 - Push Pull output 2MHz.
* 3 - Push Pull output 50MHz.
* 4 - Digital input.
* 5 - Open Drain output 10MHz.
* 6 - Open Drain output 2MHz.
* 7 - Open Drain output 50MHz.
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
* 9 - Alternate Push Pull output 10MHz.
* A - Alternate Push Pull output 2MHz.
* B - Alternate Push Pull output 50MHz.
* C - Reserved.
* D - Alternate Open Drain output 10MHz.
* E - Alternate Open Drain output 2MHz.
* F - Alternate Open Drain output 50MHz.
* Please refer to the STM32 Reference Manual for details.
*/
/*
* Port A setup.
* PA0 - input with pull-up (TIM2_CH1)
* PA1 - input with pull-down (TIM2_CH2)
* PA2 - input with pull-up (TIM2_CH3)
* PA11 - input with pull-up (USBDM)
* PA12 - input with pull-up (USBDP)
* Everything input with pull-up except:
* PA10 - Push pull output (USB 1:ON 0:OFF)
*/
#define VAL_GPIOACRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIOACRH 0x88888388 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFFFFD
/*
* Port B setup.
* Everything input with pull-up except:
* PB0 - Push pull output (LED 1:ON 0:OFF)
*/
#define VAL_GPIOBCRL 0x88888883 /* PB7...PB0 */
#define VAL_GPIOBCRH 0x88888888 /* PB15...PB8 */
#define VAL_GPIOBODR 0xFFFFFFFF
/*
* Port C setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOCCRL 0x88888888 /* PC7...PC0 */
#define VAL_GPIOCCRH 0x88888888 /* PC15...PC8 */
#define VAL_GPIOCODR 0xFFFFFFFF
/*
* Port D setup.
* Everything input with pull-up except:
* PD0 - Normal input (XTAL).
* PD1 - Normal input (XTAL).
*/
#define VAL_GPIODCRL 0x88888844 /* PD7...PD0 */
#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
#define VAL_GPIODODR 0xFFFFFFFF
/*
* Port E setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
#define VAL_GPIOEODR 0xFFFFFFFF
#endif /* _BOARD_H_ */

15
boards/FST_01/mcuconf.h Normal file
View File

@@ -0,0 +1,15 @@
/*
* HAL driver system settings.
*/
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 6
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PPRE2 STM32_PPRE2_DIV2
#define STM32_ADCPRE STM32_ADCPRE_DIV4
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_MCO STM32_MCO_NOCLOCK
#include "mcuconf-common.h"

36
boards/FST_01_00/board.c Normal file
View File

@@ -0,0 +1,36 @@
#include "config.h"
#include "ch.h"
#include "hal.h"
#include "../common/hwinit.c"
void
hwinit0 (void)
{
hwinit0_common ();
}
void
hwinit1 (void)
{
hwinit1_common ();
}
void
USB_Cable_Config (int NewState)
{
if (NewState != DISABLE)
palSetPad (IOPORT1, GPIOA_USB_ENABLE);
else
palClearPad (IOPORT1, GPIOA_USB_ENABLE);
}
void
set_led (int value)
{
if (value)
palSetPad (IOPORT1, GPIOA_LED);
else
palClearPad (IOPORT1, GPIOA_LED);
}

129
boards/FST_01_00/board.h Normal file
View File

@@ -0,0 +1,129 @@
/*
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
This file is part of ChibiOS/RT.
ChibiOS/RT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
ChibiOS/RT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
A special exception to the GPL can be applied should you wish to distribute
a combined work that includes ChibiOS/RT, without being obliged to provide
the source code for any proprietary components. See the file exception.txt
for full details of how and when the exception can be applied.
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/*
* Setup for the FST-01 board (experimental version 00).
*/
/*
* Board identifier.
*/
#define BOARD_FST_01
#define BOARD_NAME "FST-01-00"
/*
* Board frequencies.
*/
#define STM32_LSECLK 32768
#define STM32_HSECLK 8000000
/*
* MCU type, this macro is used by both the ST library and the ChibiOS/RT
* native STM32 HAL.
*/
#define STM32F10X_MD
#define CPU_WITH_NO_GPIOE 1
/*
* IO pins assignments.
*/
#define GPIOA_LED 8
#define GPIOA_USB_ENABLE 10
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
*
* The digits have the following meaning:
* 0 - Analog input.
* 1 - Push Pull output 10MHz.
* 2 - Push Pull output 2MHz.
* 3 - Push Pull output 50MHz.
* 4 - Digital input.
* 5 - Open Drain output 10MHz.
* 6 - Open Drain output 2MHz.
* 7 - Open Drain output 50MHz.
* 8 - Digital input with PullUp or PullDown resistor depending on ODR.
* 9 - Alternate Push Pull output 10MHz.
* A - Alternate Push Pull output 2MHz.
* B - Alternate Push Pull output 50MHz.
* C - Reserved.
* D - Alternate Open Drain output 10MHz.
* E - Alternate Open Drain output 2MHz.
* F - Alternate Open Drain output 50MHz.
* Please refer to the STM32 Reference Manual for details.
*/
/*
* Port A setup.
* PA11 - input with pull-up (USBDM)
* PA12 - input with pull-up (USBDP)
* Everything input with pull-up except:
* PA8 - Push pull output (LED 1:ON 0:OFF)
* PA10 - Push pull output (USB 1:ON 0:OFF)
*/
#define VAL_GPIOACRL 0x88888888 /* PA7...PA0 */
#define VAL_GPIOACRH 0x88888383 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFFFFF
/*
* Port B setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */
#define VAL_GPIOBCRH 0x88888888 /* PB15...PB8 */
#define VAL_GPIOBODR 0xFFFFFFFF
/*
* Port C setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOCCRL 0x88888888 /* PC7...PC0 */
#define VAL_GPIOCCRH 0x88888888 /* PC15...PC8 */
#define VAL_GPIOCODR 0xFFFFFFFF
/*
* Port D setup.
* Everything input with pull-up except:
* PD0 - Normal input (XTAL).
* PD1 - Normal input (XTAL).
*/
#define VAL_GPIODCRL 0x88888844 /* PD7...PD0 */
#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */
#define VAL_GPIODODR 0xFFFFFFFF
/*
* Port E setup.
* Everything input with pull-up except:
*/
#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */
#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */
#define VAL_GPIOEODR 0xFFFFFFFF
#endif /* _BOARD_H_ */

View File

@@ -0,0 +1,15 @@
/*
* HAL driver system settings.
*/
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PPRE2 STM32_PPRE2_DIV2
#define STM32_ADCPRE STM32_ADCPRE_DIV4
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_MCO STM32_MCO_NOCLOCK
#include "mcuconf-common.h"

View File

@@ -28,14 +28,14 @@
#define _BOARD_H_
/*
* Setup for the Olimex STM32-P103 proto board.
* Setup for the Olimex STM32-H103 proto board.
*/
/*
* Board identifier.
*/
#define BOARD_OLIMEX_STM32_P103
#define BOARD_NAME "Olimex STM32-P103"
#define BOARD_OLIMEX_STM32_H103
#define BOARD_NAME "Olimex STM32-H103"
/*
* Board frequencies.

View File

@@ -15,7 +15,6 @@ hwinit1 (void)
{
hwinit1_common ();
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
/* EXTI0 <= PB0 */
AFIO->EXTICR[0] = AFIO_EXTICR1_EXTI0_PB;
@@ -69,7 +68,6 @@ hwinit1 (void)
/* Generate UEV to upload PSC and ARR */
TIM4->EGR = TIM_EGR_UG;
#endif
#endif
}
void
@@ -90,7 +88,6 @@ set_led (int value)
palSetPad (IOPORT4, GPIOD_LED1);
}
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
void
cir_ext_disable (void)
@@ -156,4 +153,3 @@ CH_IRQ_HANDLER (EXTI2_IRQHandler)
CH_IRQ_EPILOGUE ();
}
#endif
#endif

View File

@@ -38,8 +38,12 @@
#define BOARD_STBEE
#define BOARD_NAME "STBee"
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DIAL_SUPPORT)
#define HAVE_7SEGLED 1
/*
* Timer assignment for CIR
*/
#define TIMx TIM3
#endif
/*
@@ -85,7 +89,7 @@
* Please refer to the STM32 Reference Manual for details.
*/
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DIAL_SUPPORT)
/*
* Port A setup.
* PA6 - (TIM3_CH1) input with pull-up

View File

@@ -15,11 +15,12 @@ hwinit1 (void)
{
hwinit1_common ();
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_SUPPORT) && !defined(DFU_SUPPORT)
palWritePort(IOPORT2, 0x7fff); /* Only clear GPIOB_7SEG_DP */
while (palReadPad (IOPORT2, GPIOB_BUTTON) != 0)
; /* Wait for JTAG debugger connection */
palWritePort(IOPORT2, 0xffff); /* All set */
#endif
#if defined(PINPAD_CIR_SUPPORT)
/* EXTI0 <= PB0 */
@@ -73,7 +74,6 @@ hwinit1 (void)
TIM4->ARR = 31;
/* Generate UEV to upload PSC and ARR */
TIM4->EGR = TIM_EGR_UG;
#endif
#endif
/*
* Disable JTAG and SWD, done after hwinit1_common as HAL resets AFIO
@@ -101,7 +101,6 @@ set_led (int value)
palSetPad (IOPORT1, GPIOA_LED1);
}
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
void
cir_ext_disable (void)
@@ -167,4 +166,3 @@ CH_IRQ_HANDLER (EXTI2_IRQHandler)
CH_IRQ_EPILOGUE ();
}
#endif
#endif

View File

@@ -39,8 +39,12 @@
#define BOARD_NAME "STBee Mini"
#define CPU_WITH_NO_GPIOE 1
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DIAL_SUPPORT)
#define HAVE_7SEGLED 1
/*
* Timer assignment for CIR
*/
#define TIMx TIM3
#endif
/*
@@ -88,7 +92,7 @@
* Please refer to the STM32 Reference Manual for details.
*/
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DIAL_SUPPORT)
/*
* Port A setup.
* PA6 - (TIM3_CH1) input with pull-up

View File

@@ -10,3 +10,5 @@
#define STM32_PPRE2 STM32_PPRE2_DIV2
#define STM32_ADCPRE STM32_ADCPRE_DIV4
#define STM32_MCO STM32_MCO_NOCLOCK
#include "mcuconf-common.h"

View File

@@ -15,7 +15,7 @@ hwinit1 (void)
{
hwinit1_common ();
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
/* EXTI5 <= PB5 */
AFIO->EXTICR[1] = AFIO_EXTICR2_EXTI5_PB;
EXTI->IMR = 0;
@@ -62,7 +62,7 @@ set_led (int value)
palClearPad (IOPORT1, GPIOA_LED);
}
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
void
cir_ext_disable (void)
{

View File

@@ -56,6 +56,11 @@
*/
#define GPIOA_LED 8
/*
* Timer assignment for CIR
*/
#define TIMx TIM3
/*
* I/O ports initial setup, this configuration is established soon after reset
* in the initialization code.
@@ -91,7 +96,7 @@
#define VAL_GPIOACRH 0x88888883 /* PA15...PA8 */
#define VAL_GPIOAODR 0xFFFFFFFF
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
/*
* Port B setup.
* Everything input with pull-up except:

View File

@@ -1,36 +1,8 @@
/* Hardware specific USB functions */
/*
* For detail, please see the documentation of
* STM32F10x USB Full Speed Device Library (USB-FS-Device_Lib)
* by STMicroelectronics' MCD Application Team
*/
/* Hardware specific function */
#include "ch.h"
#include "hal.h"
#include "board.h"
#include "usb_lib.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "hw_config.h"
#include "platform_config.h"
#include "usb_pwr.h"
void
Enter_LowPowerMode (void)
{
bDeviceState = SUSPENDED;
}
void
Leave_LowPowerMode (void)
{
DEVICE_INFO *pInfo = &Device_Info;
if (pInfo->Current_Configuration != 0)
bDeviceState = CONFIGURED;
else
bDeviceState = ATTACHED;
}
const uint8_t *
unique_device_id (void)

View File

@@ -41,7 +41,7 @@
/*
* ADC driver system settings.
*/
#define USE_STM32_ADC1 FALSE
#define USE_STM32_ADC1 TRUE
#define STM32_ADC1_DMA_PRIORITY 3
#define STM32_ADC1_IRQ_PRIORITY 5
#define STM32_ADC1_DMA_ERROR_HOOK() chSysHalt()

View File

@@ -1,28 +1,72 @@
USB communication
=================
USB communication (current)
===========================
* No command chaining, but extended APDU and extended Lc and Le.
I think that this keep the code simple.
* Get response, command chaining, short APDU only.
* Once in the past (version <= 0.4), the value of
dwMaxCCIDMessageLength was 64 and we supported ICC block chaining,
so that we could not handle multple Bulk transactions.
* Now, the value of dwMaxCCIDMessageLength is 320, that's the size
of header of ICC block plus size of maximum APDU (by 64
granularity). Still, some ccid implementation (ccid 1.3.11, for
example) sends ICC block using chaining unfortunately, so we keep
the code of ICC block chaining.
If it were only for token and no smartcard:
* Get response, command chaining and short APDU would be considered
useless.
* It would be wise to use extended APDU and CCID/ICCD block chaining.
The question would be: When lower layer (CCID/ICCD layer) support
enough mechanism of block assembly, why not use one in the application
layer (ISO 7816)?
For token implementation, CCID/ICCD would be lower layer and ISO 7816
would be higher layer, but it's different in fact. The figure of
communication is like::
host <-----------> reader <---------> smartcard
CCID/ICCD ISO 7816
host <--> token
Given the situation host side (GnuPG) already has the features of
handling get response, command chaining, and short APDU only, it is
rather better to do that on token side too.
Besides, supporting extended APDU on host side, it would be needed to
prepare 64KB buffer (that's the maximum size), as there is no explicit
limitation for buffer size. 64KB would be large, and this could be
avoided when we use short APDU only.
USB communication (second attempt)
==================================
* No get response, no command chaining, but extended APDU and extended
Lc and Le. I think that this keep the code simple.
* The value of dwMaxCCIDMessageLength is 320, that's the size
of header of ICC block plus size of maximum APDU (by 64
granularity). Still, some ccid implementation (ccid 1.3.11, for
example) sends ICC block using chaining unfortunately, so we keep
the code of ICC block chaining.
USB communication (initial attempt)
===================================
* Once in the past (version <= 0.4), the value of
dwMaxCCIDMessageLength was 64 and we supported CCID/ICCD block chaining,
so that we could not handle multple Bulk transactions.
OpenPGP card protocol implementation
====================================
I try to follow "no clear password(s)" policy, even if it is on
protected flash memory. Futher, keystrings for user and reset code
are removed after key imports. Because of this, replacing keys
are not possible without password information. Thus, replacing
existing keys are not supported.
protected flash memory. Further, keystrings for user and reset code
are removed after key imports. Because of this, replacing keys are
not possible without password information. (Thus, replacing existing
keys are not supported.)
Therefore, there is "no clear password" and "no keystrings" on flash
ROM when Gnuk is used by admin-less mode. When it is used with admin,
the keystring of admin is on flash ROM.
How a private key is stored

View File

@@ -0,0 +1,34 @@
On GNU/Linux Desktop, I use udisks-glue so that DnDpinentry folder can
be mounted with sync and noatime options.
After installing udisks-glue, I invoke gnome-session-properties to
add udisks-glue to "Startup Program".
Then, I have two files to configure udisks (disable udisks for
DnDpinentry) and udisks-glue (enable and specify options for DnDpinentry).
/etc/udev/rules.d/88-udisks.rules
---------------
ENV{ID_VENDOR}=="FSIJ", ENV{DEVTYPE}=="disk", ENV{ID_FS_LABEL}=="DnDpinentry", ENV{UDISKS_PRESENTATION_NOPOLICY}="1"
---------------
~/.udisks-glue.conf
---------------
filter gone {
label = "DnDpinentry"
optical = false
}
match gone {
automount = true
automount_options = { sync, noatime }
}
---------------
We need following setting for pinentry. Or else, you can't do
anything when pinentry grabs mouse focus.
~/.gnupg/gpg-agent.conf
---------------
no-grab
---------------

View File

@@ -3,9 +3,6 @@
BOARD_DIR=@BOARD_DIR@
@PINPAD_MAKE_OPTION@
@DEBUG_MAKE_OPTION@
ifneq ($(ENABLE_DEBUG),)
ENABLE_VCOMPORT=1
endif
##############################################################################
# Build global options
@@ -70,8 +67,6 @@ include $(CHIBIOS)/os/hal/platforms/STM32/platform.mk
include $(CHIBIOS)/os/hal/hal.mk
include $(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/port.mk
include $(CHIBIOS)/os/kernel/kernel.mk
include stmusb.mk
include vcomport.mk
include crypt.mk
# C sources that can be compiled in ARM or THUMB mode depending on the global
@@ -85,13 +80,12 @@ CSRC = $(PORTSRC) \
$(BOARD_DIR)/board.c \
$(CHIBIOS)/os/various/evtimer.c \
$(CHIBIOS)/os/various/syscalls.c \
$(STMUSBSRC) \
$(VCOMSRC) \
$(CRYPTSRC) \
main.c usb_lld.c \
usb_desc.c usb_prop.c \
usb-icc.c openpgp.c ac.c openpgp-do.c flash.c hardclock.c \
random.c
usb-icc.c openpgp.c ac.c openpgp-do.c flash.c \
random.c neug.c
ifneq ($(ENABLE_DEBUG),)
CSRC += debug.c
@@ -101,11 +95,15 @@ ifneq ($(ENABLE_PINPAD),)
CSRC += pin-$(ENABLE_PINPAD).c
endif
ifeq ($(ENABLE_PINPAD),dnd)
CSRC += usb-msc.c
endif
# List ASM source files here
ASMSRC = $(PORTASM) \
$(CHIBIOS)/os/ports/GCC/ARMCMx/STM32F10x/vectors.s
INCDIR = $(CRYPTINCDIR) $(STMUSBINCDIR) $(VCOMDIR) \
INCDIR = $(CRYPTINCDIR) \
$(PORTINC) $(KERNINC) $(TESTINC) \
$(HALINC) $(PLATFORMINC) ../boards/common $(BOARD_DIR) \
$(CHIBIOS)/os/various
@@ -205,9 +203,7 @@ ifeq ($(USE_FWLIB),yes)
endif
include $(CHIBIOS)/os/ports/GCC/ARM/rules.mk
random_bits:
dd if=/dev/random bs=1 of=random_bits count=1024
MCFLAGS= -mcpu=$(MCU) -mfix-cortex-m3-ldrd
distclean: clean
-rm -f Makefile gnuk.ld config.h random_bits
-rm -f Makefile gnuk.ld config.h *.inc

View File

@@ -57,11 +57,11 @@ ac_reset_other (void)
}
int
verify_user_0 (const uint8_t *pw, int buf_len, int pw_len_known,
verify_user_0 (uint8_t access, const uint8_t *pw, int buf_len, int pw_len_known,
const uint8_t *ks_pw1)
{
int pw_len;
int r;
int r1, r2;
uint8_t keystring[KEYSTRING_MD_SIZE];
if (gpg_pw_locked (PW_ERR_PW1))
@@ -75,7 +75,7 @@ verify_user_0 (const uint8_t *pw, int buf_len, int pw_len_known,
|| strncmp ((const char *)pw, OPENPGP_CARD_INITIAL_PW1, pw_len))
goto failure;
else
goto success;
goto success_one_step;
}
else
pw_len = ks_pw1[0];
@@ -88,15 +88,28 @@ verify_user_0 (const uint8_t *pw, int buf_len, int pw_len_known,
return -1;
}
success_one_step:
sha1 (pw, pw_len, keystring);
if ((r = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER, keystring))
< 0)
goto failure;
else if (r == 0)
if (memcmp (ks_pw1+1, keystring, KEYSTRING_MD_SIZE) != 0)
if (access == AC_PSO_CDS_AUTHORIZED)
{
r1 = gpg_do_load_prvkey (GPG_KEY_FOR_SIGNING, BY_USER, keystring);
r2 = 0;
}
else
{
r1 = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, BY_USER, keystring);
r2 = gpg_do_load_prvkey (GPG_KEY_FOR_AUTHENTICATION, BY_USER, keystring);
}
if (r1 < 0 || r2 < 0)
{
gpg_pw_increment_err_counter (PW_ERR_PW1);
return -1;
}
else if (r1 == 0 && r2 == 0)
if (ks_pw1 != NULL && memcmp (ks_pw1+1, keystring, KEYSTRING_MD_SIZE) != 0)
goto failure;
success:
gpg_pw_reset_err_counter (PW_ERR_PW1);
return pw_len;
}
@@ -113,7 +126,7 @@ verify_pso_cds (const uint8_t *pw, int pw_len)
DEBUG_INFO ("verify_pso_cds\r\n");
DEBUG_BYTE (pw_len);
r = verify_user_0 (pw, pw_len, pw_len, ks_pw1);
r = verify_user_0 (AC_PSO_CDS_AUTHORIZED, pw, pw_len, pw_len, ks_pw1);
if (r > 0)
auth_status |= AC_PSO_CDS_AUTHORIZED;
return r;
@@ -122,29 +135,16 @@ verify_pso_cds (const uint8_t *pw, int pw_len)
int
verify_other (const uint8_t *pw, int pw_len)
{
int r1, r2;
uint8_t keystring[KEYSTRING_MD_SIZE];
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
int r;
DEBUG_INFO ("verify_other\r\n");
DEBUG_BYTE (pw_len);
if (gpg_pw_locked (PW_ERR_PW1))
return 0;
sha1 (pw, pw_len, keystring);
if ((r1 = gpg_do_load_prvkey (GPG_KEY_FOR_DECRYPTION, BY_USER, keystring)) < 0
|| (r2 = gpg_do_load_prvkey (GPG_KEY_FOR_AUTHENTICATION, BY_USER,
keystring)) < 0)
{
gpg_pw_increment_err_counter (PW_ERR_PW1);
return -1;
}
else if (r1 == 0 && r2 == 0)
/* No key is available. Fail even if password can match. */
return -1;
gpg_pw_reset_err_counter (PW_ERR_PW1);
auth_status |= AC_OTHER_AUTHORIZED;
return 1;
r = verify_user_0 (AC_OTHER_AUTHORIZED, pw, pw_len, pw_len, ks_pw1);
if (r > 0)
auth_status |= AC_OTHER_AUTHORIZED;
return r;
}
/*
@@ -172,7 +172,7 @@ calc_md (int count, const uint8_t *salt, const uint8_t *pw, int pw_len,
count -= pw_len + 8;
}
if (count < 8)
if (count <= 8)
sha1_update (&sha1_ctx, salt, count);
else
{
@@ -230,7 +230,8 @@ verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known)
if (ks_pw1 != NULL)
{ /* empty PW3, but PW1 exists */
int r = verify_user_0 (pw, buf_len, pw_len_known, ks_pw1);
int r = verify_user_0 (AC_PSO_CDS_AUTHORIZED,
pw, buf_len, pw_len_known, ks_pw1);
if (r > 0)
admin_authorized = BY_USER;

View File

@@ -1,7 +1,7 @@
/*
* call-rsa.c -- Glue code between RSA computation and OpenPGP card protocol
*
* Copyright (C) 2010 Free Software Initiative of Japan
* Copyright (C) 2010, 2011 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -25,10 +25,13 @@
#include "config.h"
#include "ch.h"
#include "gnuk.h"
#include "openpgp.h"
#include "polarssl/config.h"
#include "polarssl/rsa.h"
#define RSA_SIGNATURE_LENGTH 256 /* 256 byte == 2048-bit */
#define RSA_SIGNATURE_LENGTH KEY_CONTENT_LEN
/* 256 byte == 2048-bit */
/* 128 byte == 1024-bit */
static rsa_context rsa_ctx;
@@ -43,10 +46,10 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
mpi_init (&P1, &Q1, &H, NULL);
rsa_init (&rsa_ctx, RSA_PKCS_V15, 0);
rsa_ctx.len = 2048 / 8;
rsa_ctx.len = KEY_CONTENT_LEN;
mpi_read_string (&rsa_ctx.E, 16, "10001");
mpi_read_binary (&rsa_ctx.P, &kd->data[0], rsa_ctx.len / 2);
mpi_read_binary (&rsa_ctx.Q, &kd->data[128], rsa_ctx.len / 2);
mpi_read_binary (&rsa_ctx.Q, &kd->data[KEY_CONTENT_LEN/2], rsa_ctx.len / 2);
mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q);
mpi_sub_int (&P1, &rsa_ctx.P, 1);
mpi_sub_int (&Q1, &rsa_ctx.Q, 1);
@@ -82,31 +85,32 @@ rsa_sign (const uint8_t *raw_message, uint8_t *output, int msg_len,
}
else
{
res_APDU[RSA_SIGNATURE_LENGTH] = 0x90;
res_APDU[RSA_SIGNATURE_LENGTH+1] = 0x00;
res_APDU_size = RSA_SIGNATURE_LENGTH + 2;
res_APDU_size = RSA_SIGNATURE_LENGTH;
DEBUG_INFO ("done.\r\n");
GPG_SUCCESS ();
return 0;
}
}
/*
* LEN: length in byte
*/
const uint8_t *
modulus_calc (const uint8_t *p, int len)
{
mpi P, Q, N;
uint8_t *modulus;
(void)len; /* 2048-bit assumed */
modulus = malloc (2048 / 8);
modulus = malloc (len);
if (modulus == NULL)
return NULL;
mpi_init (&P, &Q, &N, NULL);
mpi_read_binary (&P, p, 2048 / 8 / 2);
mpi_read_binary (&Q, p + 128, 2048 / 8 / 2);
mpi_read_binary (&P, p, len / 2);
mpi_read_binary (&Q, p + len / 2, len / 2);
mpi_mul_mpi (&N, &P, &Q);
mpi_write_binary (&N, modulus, 2048 / 8);
mpi_write_binary (&N, modulus, len);
mpi_free (&P, &Q, &N, NULL);
return modulus;
}
@@ -135,8 +139,9 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
DEBUG_WORD (msg_len);
mpi_read_string (&rsa_ctx.E, 16, "10001");
mpi_read_binary (&rsa_ctx.P, &kd->data[0], 2048 / 8 / 2);
mpi_read_binary (&rsa_ctx.Q, &kd->data[128], 2048 / 8 / 2);
mpi_read_binary (&rsa_ctx.P, &kd->data[0], KEY_CONTENT_LEN / 2);
mpi_read_binary (&rsa_ctx.Q, &kd->data[KEY_CONTENT_LEN/2],
KEY_CONTENT_LEN / 2);
mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q);
mpi_sub_int (&P1, &rsa_ctx.P, 1);
mpi_sub_int (&Q1, &rsa_ctx.Q, 1);
@@ -162,7 +167,7 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
#endif
r = rsa_pkcs1_decrypt (&rsa_ctx, RSA_PRIVATE, &output_len,
input, output, MAX_RES_APDU_SIZE - 2);
input, output, MAX_RES_APDU_DATA_SIZE);
rsa_free (&rsa_ctx);
if (r < 0)
{
@@ -172,10 +177,9 @@ rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len,
}
else
{
res_APDU[output_len] = 0x90;
res_APDU[output_len+1] = 0x00;
res_APDU_size = output_len + 2;
res_APDU_size = output_len;
DEBUG_INFO ("done.\r\n");
GPG_SUCCESS ();
return 0;
}
}

View File

@@ -10,7 +10,7 @@
#define CH_OPTIMIZE_SPEED TRUE
#define CH_USE_REGISTRY TRUE
#define CH_USE_WAITEXIT TRUE
#define CH_USE_SEMAPHORES FALSE
#define CH_USE_SEMAPHORES TRUE
#define CH_USE_SEMAPHORES_PRIORITY FALSE
#define CH_USE_SEMSW FALSE
#define CH_USE_MUTEXES TRUE

View File

@@ -5,3 +5,4 @@
@DFU_DEFINE@
@PINPAD_DEFINE@
@PINPAD_MORE_DEFINE@
@CERTDO_DEFINE@

91
src/configure vendored
View File

@@ -3,7 +3,7 @@
#
# This file is *NOT* generated by GNU Autoconf, but written by NIIBE Yutaka
#
# Copyright (C) 2010, 2011 Free Software Initiative of Japan
# Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
#
# This file is a part of Gnuk, a GnuPG USB Token implementation.
# Gnuk is free software: you can redistribute it and/or modify it
@@ -21,17 +21,13 @@
# Default settings
help=no
vidpid=none
target=OLIMEX_STM32_H103
verbose=no
with_dfu=default
debug=no
pinpad=no
# check /dev/random
if test ! -e /dev/random; then
echo "/dev/random is required." >&2
exit 1
fi
certdo=no
# Process each option
for option; do
@@ -43,10 +39,12 @@ for option; do
case $option in
-h | --help)
help=yes ;;
--target=*)
target=$optarg ;;
-v | --verbose)
verbose=yes ;;
--vidpid=*)
vidpid=$optarg ;;
--target=*)
target=$optarg ;;
--enable-debug)
debug=yes ;;
--disable-debug)
@@ -57,6 +55,10 @@ for option; do
pinpad=$optarg ;;
--disable-pinpad)
pinpad=no ;;
--enable-certdo)
certdo=yes ;;
--disable-certdo)
certdo=no ;;
--with-dfu)
with_dfu=yes ;;
--without-dfu)
@@ -77,6 +79,7 @@ Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit [no]
--vidpid=VID:PID specify vendor/product ID [<NONE>]
--target=TARGET specify target [OLIMEX_STM32_H103]
supported targes are:
OLIMEX_STM32_H103
@@ -85,14 +88,50 @@ Configuration:
STBEE_MINI
STM8S_DISCOVERY
STBEE
FST_01
--enable-debug debug with virtual COM port [no]
--enable-pinpad={cir,dial}
PIN input device support [no]
--enable-pinpad={dnd,cir,dial}
PIN entry support [no]
--enable-certdo support CERT.3 data object [no]
--with-dfu build image for DFU [<target specific>]
EOF
exit 0
fi
if test "$vidpid" = "none"; then
echo "Please specify Vendor ID and Product ID by --vidpid option."
exit 1
fi
if !(IFS=" "
while read VIDPID VERSION PRODUCT VENDOR; do
if test "$vidpid" = "$VIDPID"; then
(echo $VIDPID | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\):\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* idVendor */\n 0x\4, 0x\3, /* idProduct */%p"
echo $VERSION | sed -n -e "s%^\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)$% 0x\2, 0x\1, /* bcdDevice */%p"
) > usb-vid-pid-ver.c.inc
(echo 'static const uint8_t gnukStringVendor[] = {'
echo " ${#VENDOR}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Manufacturer: \"$VENDOR\" */"
echo $VENDOR | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
echo
echo 'static const uint8_t gnukStringProduct[] = {'
echo " ${#PRODUCT}*2+2, /* bLength */"
echo " USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */"
echo " /* Product name: \"$PRODUCT\" */"
echo $PRODUCT | sed -n -e "s/\(........\)/\1\n/gp" | sed -n -e "s/\(.\)/'\1', 0, /g" -e "s/^/ /" -e "s/ $//p"
echo '};'
) >usb-string-vendor-product.c.inc
exit 0
fi
done; exit 1) < ../GNUK_USB_DEVICE_ID
then
echo "Please specify valid Vendor ID and Product ID."
echo "Check ../GNUK_USB_DEVICE_ID."
exit 1
fi
BOARD_DIR=../boards/$target
if test -d $BOARD_DIR; then
echo "Configured for target: $target"
@@ -159,10 +198,10 @@ if test "$pinpad" = "no"; then
PINPAD_MORE_DEFINE=""
echo "PIN pad option disabled"
elif test "$pinpad" = "yes"; then
PINPAD_MAKE_OPTION="ENABLE_PINPAD=cir"
PINPAD_MAKE_OPTION="ENABLE_PINPAD=dnd"
PINPAD_DEFINE="#define PINPAD_SUPPORT 1"
PINPAD_MORE_DEFINE="#define PINPAD_CIR_SUPPORT 1"
echo "PIN pad option enabled (cir)"
PINPAD_MORE_DEFINE="#define PINPAD_DND_SUPPORT 1"
echo "PIN pad option enabled (dnd)"
else
PINPAD_MAKE_OPTION="ENABLE_PINPAD=$pinpad"
PINPAD_DEFINE="#define PINPAD_SUPPORT 1"
@@ -170,16 +209,34 @@ else
echo "PIN pad option enabled ($pinpad)"
fi
# --enable-certdo option
if test "$certdo" = "yes"; then
CERTDO_DEFINE="#define CERTDO_SUPPORT 1"
echo "CERT.3 Data Object is supported"
else
CERTDO_DEFINE="#undef CERTDO_SUPPORT"
echo "CERT.3 Data Object is not supported"
fi
sed -e "s%@BOARD_DIR@%$BOARD_DIR%" \
-e "s%@DEBUG_MAKE_OPTION@%$DEBUG_MAKE_OPTION%" \
-e "s%@PINPAD_MAKE_OPTION@%$PINPAD_MAKE_OPTION%" \
< Makefile.in > Makefile
sed -e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
if test "$certdo" = "yes"; then
sed -e "/^@CERTDO_SUPPORT_START@$/ d" -e "/^@CERTDO_SUPPORT_END@$/ d" \
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
< gnuk.ld.in > gnuk.ld
else
sed -e "/^@CERTDO_SUPPORT_START@$/,/^@CERTDO_SUPPORT_END@$/ d" \
-e "s/@ORIGIN@/$ORIGIN/" -e "s/@FLASH_SIZE@/$FLASH_SIZE/" \
-e "s/@FLASH_PAGE_SIZE@/$FLASH_PAGE_SIZE/" \
< gnuk.ld.in > gnuk.ld
fi
sed -e "s/@DEBUG_DEFINE@/$DEBUG_DEFINE/" \
-e "s/@DFU_DEFINE@/$DFU_DEFINE/" \
-e "s/@PINPAD_DEFINE@/$PINPAD_DEFINE/" \
-e "s/@PINPAD_MORE_DEFINE@/$PINPAD_MORE_DEFINE/" \
-e "s/@DFU_DEFINE@/$DFU_DEFINE/" \
-e "s/@CERTDO_DEFINE@/$CERTDO_DEFINE/" \
< config.h.in > config.h
exit 0

View File

@@ -1,7 +1,7 @@
/*
* flash.c -- Data Objects (DO) and GPG Key handling on Flash ROM
*
* Copyright (C) 2010, 2011 Free Software Initiative of Japan
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -147,8 +147,6 @@ flash_erase_page (uint32_t addr)
* .bss
* _end
* <alignment to page>
* random_bits_start
* <one page>
* ch_certificate_startp
* <2048 bytes>
* _data_pool
@@ -313,7 +311,6 @@ flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *data, int len)
hw = data[i*2] | 0xff00;
if (flash_program_halfword (addr, hw) != FLASH_COMPLETE)
flash_warning ("DO WRITE ERROR");
addr += 2;
}
}
@@ -371,7 +368,6 @@ flash_do_release (const uint8_t *do_data)
{
if (flash_program_halfword (addr, 0) != FLASH_COMPLETE)
flash_warning ("fill-zero pad failure");
addr += 2;
}
/* Fill 0x0000 for "tag_number and length" word */
@@ -583,6 +579,7 @@ flash_cnt123_clear (const uint8_t **addr_p)
}
#if defined(CERTDO_SUPPORT)
static int
flash_check_blank (const uint8_t *page, int size)
{
@@ -594,17 +591,16 @@ flash_check_blank (const uint8_t *page, int size)
return 1;
}
#endif
#define FLASH_CH_CERTIFICATE_SIZE 2048
int
flash_erase_binary (uint8_t file_id)
{
const uint8_t *p;
#if defined(CERTDO_SUPPORT)
if (file_id == FILEID_CH_CERTIFICATE)
{
p = &ch_certificate_start;
const uint8_t *p = &ch_certificate_start;
if (flash_check_blank (p, FLASH_CH_CERTIFICATE_SIZE) == 0)
{
flash_erase_page ((uint32_t)p);
@@ -613,18 +609,12 @@ flash_erase_binary (uint8_t file_id)
#endif
}
return 0;
}
else if (file_id == FILEID_RANDOM)
{
p = &random_bits_start;
if (flash_check_blank (p, FLASH_PAGE_SIZE) == 0)
flash_erase_page ((uint32_t)p);
return 0;
}
else
#else
(void)file_id;
#endif
return -1;
}
@@ -636,17 +626,15 @@ flash_write_binary (uint8_t file_id, const uint8_t *data,
uint16_t maxsize;
const uint8_t *p;
#if defined(CERTDO_SUPPORT)
if (file_id == FILEID_CH_CERTIFICATE)
{
maxsize = FLASH_CH_CERTIFICATE_SIZE;
p = &ch_certificate_start;
}
else if (file_id == FILEID_RANDOM)
{
maxsize = FLASH_PAGE_SIZE;
p = &random_bits_start;
}
else if (file_id == FILEID_SERIAL_NO)
else
#endif
if (file_id == FILEID_SERIAL_NO)
{
maxsize = 6;
p = &openpgpcard_aid[8];

View File

@@ -1,3 +1,17 @@
/*
* We declare some of libc functions here, because we will
* remove dependency on libc in future, possibly.
*/
extern size_t strlen (const char *s);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern void *memcpy (void *dest, const void *src, size_t n);
extern void *memset (void *s, int c, size_t n);
extern int memcmp (const void *s1, const void *s2, size_t n);
extern void *memmove(void *dest, const void *src, size_t n);
/*
* Debug functions
*/
extern Thread *stdout_thread;
#define EV_TX_READY ((eventmask_t)1)
@@ -11,44 +25,49 @@ extern void put_binary (const char *s, int len);
extern void _write (const char *, int);
/*
* We declare some of libc functions here, because we will
* remove dependency on libc in future.
* Application layer <-> CCID layer data structure
*/
extern size_t strlen (const char *s);
extern int strncmp(const char *s1, const char *s2, size_t n);
extern void *memcpy (void *dest, const void *src, size_t n);
extern void *memset (void *s, int c, size_t n);
extern int memcmp (const void *s1, const void *s2, size_t n);
extern void *memmove(void *dest, const void *src, size_t n);
struct apdu {
uint8_t seq;
/* command APDU */
uint8_t *cmd_apdu_head; /* CLS INS P1 P2 [ internal Lc ] */
uint8_t *cmd_apdu_data;
uint16_t cmd_apdu_data_len; /* Nc, calculated by Lc field */
uint16_t expected_res_size; /* Ne, calculated by Le field */
/* response APDU */
uint16_t sw;
uint8_t *res_apdu_data;
uint16_t res_apdu_data_len;
};
extern struct apdu apdu;
#define EV_EXEC_FINISHED ((eventmask_t)2) /* GPG Execution finished */
/* maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */
#define MAX_CMD_APDU_SIZE (7+282) /* header + data */
/* maximum res apdu data is public key 5+9+256+2 (gpg_do_public_key) */
#define MAX_RES_APDU_SIZE ((5+9+256)+2) /* Data + status */
/* GPG thread */
#define EV_PINPAD_INPUT_DONE ((eventmask_t)1)
#define EV_NOP ((eventmask_t)2)
#define EV_CMD_AVAILABLE ((eventmask_t)4)
#define EV_VERIFY_CMD_AVAILABLE ((eventmask_t)8)
#define EV_MODIFY_CMD_AVAILABLE ((eventmask_t)16)
/* Maximum cmd apdu data is key import 22+4+128+128 (proc_key_import) */
#define MAX_CMD_APDU_DATA_SIZE (22+4+128+128) /* without header */
/* Maximum res apdu data is public key 5+9+256 (gpg_do_public_key) */
#define MAX_RES_APDU_DATA_SIZE (5+9+256) /* without trailer */
#define ICC_MSG_HEADER_SIZE 10
#define cmd_APDU (&icc_buffer[ICC_MSG_HEADER_SIZE])
#define res_APDU (&icc_buffer[ICC_MSG_HEADER_SIZE])
extern int icc_data_size;
#define cmd_APDU_size icc_data_size
extern int res_APDU_size;
extern const uint8_t *res_APDU_pointer;
#define res_APDU apdu.res_apdu_data
#define res_APDU_size apdu.res_apdu_data_len
/* USB buffer size of LL (Low-level): size of single Bulk transaction */
#define USB_LL_BUF_SIZE 64
/*
* USB buffer size of USB-ICC driver
* (Changing this, dwMaxCCIDMessageLength too !!)
*/
#define USB_BUF_SIZE ((10 + 10 + MAX_CMD_APDU_SIZE + USB_LL_BUF_SIZE - 1) \
/ USB_LL_BUF_SIZE * USB_LL_BUF_SIZE)
extern uint8_t icc_buffer[USB_BUF_SIZE];
enum icc_state
{
ICC_STATE_START, /* Initial */
@@ -59,7 +78,7 @@ enum icc_state
ICC_STATE_SEND, /* APDU Sent Partially */
};
extern volatile enum icc_state icc_state;
extern enum icc_state *icc_state_p;
extern volatile uint8_t auth_status;
#define AC_NONE_AUTHORIZED 0x00
@@ -79,8 +98,8 @@ extern void gpg_pw_increment_err_counter (uint8_t which);
extern int ac_check_status (uint8_t ac_flag);
extern int verify_pso_cds (const uint8_t *pw, int pw_len);
extern int verify_other (const uint8_t *pw, int pw_len);
extern int verify_user_0 (const uint8_t *pw, int buf_len, int pw_len_known,
const uint8_t *ks_pw1);
extern int verify_user_0 (uint8_t access, const uint8_t *pw, int buf_len,
int pw_len_known, const uint8_t *ks_pw1);
extern int verify_admin (const uint8_t *pw, int pw_len);
extern int verify_admin_0 (const uint8_t *pw, int buf_len, int pw_len_known);
@@ -90,7 +109,7 @@ extern void ac_reset_admin (void);
extern void ac_fini (void);
extern void set_res_apdu (uint8_t sw1, uint8_t sw2);
extern void set_res_sw (uint8_t sw1, uint8_t sw2);
extern uint16_t data_objects_number_of_bytes;
extern void gpg_data_scan (const uint8_t *p);
@@ -292,6 +311,7 @@ extern uint8_t admin_authorized;
#define SIZE_PW_STATUS_BYTES 7
extern void random_init (void);
/* 16-byte random bytes */
extern const uint8_t *random_bytes_get (void);
extern void random_bytes_free (const uint8_t *);
@@ -332,14 +352,30 @@ extern void flash_do_write_internal (const uint8_t *p, int nr, const uint8_t *da
extern const unsigned char *unique_device_id (void);
extern const uint8_t gnukStringSerial[];
#define LED_ONESHOT_SHORT ((eventmask_t)1)
#define LED_ONESHOT_LONG ((eventmask_t)2)
#define LED_TWOSHOT ((eventmask_t)4)
#define LED_STATUS_MODE ((eventmask_t)8)
#define LED_INPUT_MODE ((eventmask_t)16)
#define LED_FATAL_MODE ((eventmask_t)32)
extern Thread *main_thread;
extern void led_blink (int spec);
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
# if defined(PINPAD_CIR_SUPPORT)
extern void cir_ext_disable (void);
extern void cir_ext_enable (void);
#elif defined(PINPAD_DIAL_SUPPORT)
# elif defined(PINPAD_DIAL_SUPPORT)
extern void dial_sw_disable (void);
extern void dial_sw_enable (void);
#endif
# elif defined(PINPAD_DND_SUPPORT)
extern uint8_t media_available;
extern void msc_init (void);
extern void msc_media_insert_change (int available);
extern int msc_scsi_write (uint32_t lba, const uint8_t *buf, size_t size);
extern int msc_scsi_read (uint32_t lba, const uint8_t **sector_p);
extern void msc_scsi_stop (uint8_t code);
# endif
#define PIN_INPUT_CURRENT 1
#define PIN_INPUT_NEW 2
#define PIN_INPUT_CONFIRM 3
@@ -347,5 +383,6 @@ extern void dial_sw_enable (void);
extern uint8_t pin_input_buffer[MAX_PIN_CHARS];
extern uint8_t pin_input_len;
extern msg_t pin_main (void *arg);
extern int pinpad_getline (int msg_code, systime_t timeout);
#endif

View File

@@ -28,7 +28,8 @@
* ST32F103 memory setup.
*/
__main_stack_size__ = 0x0400;
__stacks_total_size__ = __main_stack_size__;
__process_stack_size__ = 0x0200;
__stacks_total_size__ = __main_stack_size__ + __process_stack_size__;
MEMORY
{
@@ -114,14 +115,7 @@ SECTIONS
PROVIDE(end = .);
_end = .;
.gnuk_random :
{
. = ALIGN (@FLASH_PAGE_SIZE@);
random_bits_start = .;
LONG(0xffffffff);
. = ALIGN (@FLASH_PAGE_SIZE@);
} > flash =0xffffffff
@CERTDO_SUPPORT_START@
.gnuk_ch_certificate :
{
. = ALIGN (@FLASH_PAGE_SIZE@);
@@ -130,9 +124,11 @@ SECTIONS
. += 1920;
. = ALIGN (@FLASH_PAGE_SIZE@);
} > flash =0xffffffff
@CERTDO_SUPPORT_END@
.gnuk_flash :
{
. = ALIGN (@FLASH_PAGE_SIZE@);
_data_pool = .;
KEEP(*(.gnuk_data))
. = ALIGN(@FLASH_PAGE_SIZE@);

View File

@@ -6,7 +6,7 @@
#include "mcuconf.h"
#define CH_HAL_USE_PAL TRUE
#define CH_HAL_USE_ADC FALSE
#define CH_HAL_USE_ADC TRUE
#define CH_HAL_USE_CAN FALSE
#define CH_HAL_USE_MAC FALSE
#define CH_HAL_USE_PWM FALSE

View File

@@ -1,14 +0,0 @@
#include "config.h"
#include "ch.h"
#include "hal.h"
#include "gnuk.h"
uint32_t
hardclock (void)
{
uint32_t r = SysTick->VAL;
DEBUG_INFO ("Random: ");
DEBUG_WORD (r);
return r;
}

View File

@@ -1,7 +1,7 @@
/*
* main.c - main routine of Gnuk
*
* Copyright (C) 2010 Free Software Initiative of Japan
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -22,16 +22,10 @@
*/
#include "config.h"
#include "usb_lib.h"
#include "ch.h"
#include "gnuk.h"
#include "usb_lld.h"
#include "usb_istr.h"
#include "usb_desc.h"
#include "hw_config.h"
#include "usb_pwr.h"
#include "usb-cdc.h"
#ifdef DEBUG
struct stdout {
@@ -106,10 +100,14 @@ STDOUTthread (void *arg)
p = stdout.str;
len = stdout.size;
while (len > 0)
while (1)
{
int i;
if (len == 0)
if (count_in != VIRTUAL_COM_PORT_DATA_SIZE)
break;
if (len < VIRTUAL_COM_PORT_DATA_SIZE)
{
for (i = 0; i < len; i++)
@@ -128,8 +126,7 @@ STDOUTthread (void *arg)
chEvtClear (EV_TX_READY);
USB_SIL_Write (EP3_IN, buffer_in, count_in);
SetEPTxValid (ENDP3);
usb_lld_write (ENDP3, buffer_in, count_in);
chEvtWaitOne (EV_TX_READY);
}
@@ -143,6 +140,19 @@ STDOUTthread (void *arg)
goto again;
return 0;
}
void
EP3_IN_Callback (void)
{
if (stdout_thread)
chEvtSignalI (stdout_thread, EV_TX_READY);
}
void
EP5_OUT_Callback (void)
{
usb_lld_rx_enable (ENDP5);
}
#else
void
_write (const char *s, int size)
@@ -164,7 +174,7 @@ extern msg_t USBthread (void *arg);
#define LED_TIMEOUT_STOP MS2ST(500)
#define ID_OFFSET 12
#define ID_OFFSET 22
static void
device_initialize_once (void)
{
@@ -196,6 +206,168 @@ device_initialize_once (void)
static volatile uint8_t fatal_code;
Thread *main_thread;
#define GNUK_INIT 0
#define GNUK_RUNNING 1
#define GNUK_INPUT_WAIT 2
#define GNUK_FATAL 255
/*
* 0 for initializing
* 1 for normal mode
* 2 for input waiting
* 255 for fatal
*/
static uint8_t main_mode;
static void display_interaction (void)
{
eventmask_t m;
while (1)
{
m = chEvtWaitOne (ALL_EVENTS);
set_led (1);
switch (m)
{
case LED_ONESHOT_SHORT:
chThdSleep (MS2ST (100));
break;
case LED_ONESHOT_LONG:
chThdSleep (MS2ST (400));
break;
case LED_TWOSHOT:
chThdSleep (MS2ST (50));
set_led (0);
chThdSleep (MS2ST (50));
set_led (1);
chThdSleep (MS2ST (50));
break;
case LED_STATUS_MODE:
chThdSleep (MS2ST (400));
set_led (0);
return;
case LED_FATAL_MODE:
main_mode = GNUK_FATAL;
set_led (0);
return;
default:
break;
}
set_led (0);
}
}
static void display_fatal_code (void)
{
set_led (1);
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_STOP);
set_led (1);
if (fatal_code & 1)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
if (fatal_code & 2)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_STOP);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
}
static void display_status_code (void)
{
enum icc_state icc_state;
if (icc_state_p == NULL)
icc_state = ICC_STATE_START;
else
icc_state = *icc_state_p;
if (icc_state == ICC_STATE_START)
{
set_led (1);
chThdSleep (LED_TIMEOUT_ONE);
set_led (0);
chThdSleep (LED_TIMEOUT_STOP * 3);
}
else
/* GPGthread running */
{
set_led (1);
if ((auth_status & AC_ADMIN_AUTHORIZED) != 0)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
if ((auth_status & AC_OTHER_AUTHORIZED) != 0)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
if ((auth_status & AC_PSO_CDS_AUTHORIZED) != 0)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
if (icc_state == ICC_STATE_WAIT)
{
set_led (0);
chThdSleep (LED_TIMEOUT_STOP * 2);
}
else if (icc_state == ICC_STATE_RECEIVE)
{
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_ONE);
set_led (0);
chThdSleep (LED_TIMEOUT_STOP);
}
else
{
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_STOP);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
}
}
}
void
led_blink (int spec)
{
if (spec == 0)
chEvtSignal (main_thread, LED_ONESHOT_SHORT);
else if (spec == 1)
chEvtSignal (main_thread, LED_ONESHOT_LONG);
else
chEvtSignal (main_thread, LED_TWOSHOT);
}
/*
* Entry point.
*
@@ -210,10 +382,20 @@ main (int argc, char **argv)
(void)argc;
(void)argv;
main_thread = chThdSelf ();
flash_unlock ();
device_initialize_once ();
usb_lld_init ();
USB_Init();
random_init ();
while (1)
{
if (bDeviceState != UNCONNECTED)
break;
chThdSleepMilliseconds (250);
}
#ifdef DEBUG
stdout_init ();
@@ -228,107 +410,53 @@ main (int argc, char **argv)
chThdCreateStatic (waUSBthread, sizeof(waUSBthread),
NORMALPRIO, USBthread, NULL);
#ifdef PINPAD_DND_SUPPORT
msc_init ();
#endif
while (1)
{
eventmask_t m;
count++;
if (fatal_code != 0)
m = chEvtWaitOneTimeout (ALL_EVENTS, LED_TIMEOUT_INTERVAL);
switch (m)
{
case LED_STATUS_MODE:
main_mode = GNUK_RUNNING;
break;
case LED_FATAL_MODE:
main_mode = GNUK_FATAL;
break;
case LED_INPUT_MODE:
main_mode = GNUK_INPUT_WAIT;
set_led (1);
chThdSleep (LED_TIMEOUT_ZERO);
chThdSleep (MS2ST (400));
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_STOP);
set_led (1);
if (fatal_code & 1)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
if (fatal_code & 2)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_STOP);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
}
break;
default:
break;
}
if (bDeviceState != CONFIGURED)
switch (main_mode)
{
case GNUK_FATAL:
display_fatal_code ();
break;
case GNUK_INIT:
set_led (1);
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_STOP * 3);
}
else
/* Device configured */
if (icc_state == ICC_STATE_START)
{
set_led (1);
chThdSleep (LED_TIMEOUT_ONE);
set_led (0);
chThdSleep (LED_TIMEOUT_STOP * 3);
}
else
/* GPGthread running */
{
set_led (1);
if ((auth_status & AC_ADMIN_AUTHORIZED) != 0)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
if ((auth_status & AC_OTHER_AUTHORIZED) != 0)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
if ((auth_status & AC_PSO_CDS_AUTHORIZED) != 0)
chThdSleep (LED_TIMEOUT_ONE);
else
chThdSleep (LED_TIMEOUT_ZERO);
if (icc_state == ICC_STATE_WAIT)
{
set_led (0);
chThdSleep (LED_TIMEOUT_STOP * 2);
}
else if (icc_state == ICC_STATE_RECEIVE)
{
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_ONE);
set_led (0);
chThdSleep (LED_TIMEOUT_STOP);
}
else
{
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
set_led (1);
chThdSleep (LED_TIMEOUT_STOP);
set_led (0);
chThdSleep (LED_TIMEOUT_INTERVAL);
}
}
break;
case GNUK_INPUT_WAIT:
display_interaction ();
break;
case GNUK_RUNNING:
default:
display_status_code ();
break;
}
#ifdef DEBUG_MORE
if (bDeviceState == CONFIGURED && (count % 10) == 0)
@@ -348,6 +476,7 @@ void
fatal (uint8_t code)
{
fatal_code = code;
chEvtSignal (main_thread, LED_FATAL_MODE);
_write ("fatal\r\n", 7);
for (;;);
}

453
src/neug.c Normal file
View File

@@ -0,0 +1,453 @@
/*
* neug.c - random number generation (from NeuG/src/random.c)
*
* Copyright (C) 2011 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of NeuG, a Random Number Generator
* implementation (for STM32F103).
*
* NeuG is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "ch.h"
#include "hal.h"
static Thread *rng_thread;
#define ADC_DATA_AVAILABLE ((eventmask_t)1)
/* Total number of channels to be sampled by a single ADC operation.*/
#define ADC_GRP1_NUM_CHANNELS 2
/* Depth of the conversion buffer, channels are sampled one time each.*/
#define ADC_GRP1_BUF_DEPTH 4
/*
* ADC samples buffer.
*/
static adcsample_t samp[ADC_GRP1_NUM_CHANNELS * ADC_GRP1_BUF_DEPTH];
static void adccb (adcsample_t *buffer, size_t n);
/*
* ADC conversion group.
* Mode: Linear buffer, 4 samples of 2 channels, SW triggered.
* Channels: Vref (1.5 cycles sample time, violating the spec.)
* Sensor (1.5 cycles sample time, violating the spec.)
*/
static const ADCConversionGroup adcgrpcfg = {
FALSE,
ADC_GRP1_NUM_CHANNELS,
0,
ADC_CR2_EXTSEL_SWSTART | ADC_CR2_TSVREFE | ADC_CR2_CONT,
ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_1P5) | ADC_SMPR1_SMP_VREF(ADC_SAMPLE_1P5),
0,
ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS),
0,
ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR) | ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT)
};
/*
* ADC end conversion callback.
*/
static void adccb (adcsample_t *buffer, size_t n)
{
ADCDriver *adcp = &ADCD1;
(void) buffer; (void) n;
if (adcp->ad_state == ADC_COMPLETE)
chEvtSignalI (rng_thread, ADC_DATA_AVAILABLE);
}
/*
* TinyMT routines.
*
* See
* "Tiny Mersenne Twister (TinyMT): A small-sized variant of Mersenne Twister"
* by Mutsuo Saito and Makoto Matsumoto
* http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/
*/
/* Use the first example of TinyMT */
#define TMT_MAT1 0x8f7011ee
#define TMT_MAT2 0xfc78ff1f
#define TMT_TMAT 0x3793fdff
static uint32_t tmt[4];
static void tmt_one_step (void);
#define TMT_INIT_MIN_LOOP 8
#define TMT_INIT_PRE_LOOP 8
/**
* @brief TinyMT initialize function.
*/
static void tmt_init (uint32_t seed)
{
int i;
tmt[0] = seed;
tmt[1] = TMT_MAT1;
tmt[2] = TMT_MAT2;
tmt[3] = TMT_TMAT;
for (i = 1; i < TMT_INIT_MIN_LOOP; i++)
tmt[i & 3] ^= i + UINT32_C(1812433253) * (tmt[(i - 1) & 3]
^ (tmt[(i - 1) & 3] >> 30));
if ((tmt[0] & 0x7fffffff) == 0 && tmt[1] == 0 && tmt[2] == 0 && tmt[3] == 0)
{ /* Prevent all zero */
tmt[0] = 'T';
tmt[1] = 'I';
tmt[2] = 'N';
tmt[3] = 'Y';
}
for (i = 0; i < TMT_INIT_PRE_LOOP; i++)
tmt_one_step ();
}
/**
* @brief TinyMT one step function, call this every time before tmt_value.
*/
static void tmt_one_step (void)
{
uint32_t x, y;
y = tmt[3];
x = (tmt[0] & 0x7fffffff) ^ tmt[1] ^ tmt[2];
x ^= (x << 1);
y ^= (y >> 1) ^ x;
tmt[0] = tmt[1];
tmt[1] = tmt[2];
tmt[2] = x ^ (y << 10);
tmt[3] = y;
if ((y & 1))
{
tmt[1] ^= TMT_MAT1;
tmt[2] ^= TMT_MAT2;
}
}
/**
* @brief Get a random word (32-bit).
*/
static uint32_t tmt_value (void)
{
uint32_t t0, t1;
t0 = tmt[3];
t1 = tmt[0] + (tmt[2] >> 8);
t0 ^= t1;
if ((t1 & 1))
t0 ^= TMT_TMAT;
return t0;
}
/* 8 parallel CRC-16 shift registers, with randomly rotated feedback */
#define EPOOL_SIZE 16
static uint8_t epool[EPOOL_SIZE]; /* Big-endian */
static uint8_t ep_count;
/*
* Magic number seven.
*
* We did an experiment of measuring entropy of ADC output with MUST.
* The entropy of a byte by raw sampling of LSBs has more than 6.0 bit/byte.
* So, it is considered OK to get 4-byte from 7-byte (6x7 = 42 > 32).
*/
#define NUM_NOISE_INPUTS 7
#define SHIFT_RIGHT(f) ((f)>>1)
static void ep_add (uint8_t entropy_bits, uint8_t another_random_bit)
{
uint8_t v = epool[ep_count];
/* CRC-16-CCITT's Polynomial is: x^16 + x^12 + x^5 + 1 */
epool[(ep_count - 12)& 0x0f] ^= v;
epool[(ep_count - 5)& 0x0f] ^= v;
epool[ep_count] = SHIFT_RIGHT (v) ^ entropy_bits;
if ((v&1) || another_random_bit)
epool[ep_count] ^= 0xff;
ep_count = (ep_count + 1) & 0x0f;
}
#define FNV_INIT 2166136261U
#define FNV_PRIME 16777619
static uint32_t fnv32_hash (const uint8_t *buf, int len)
{
uint32_t v = FNV_INIT;
int i;
for (i = 0; i < len; i++)
{
v ^= buf[i];
v *= FNV_PRIME;
}
return v;
}
#define PROBABILITY_50_BY_TICK() ((SysTick->VAL & 0x02) != 0)
static uint32_t ep_output (void)
{
int i;
uint8_t buf[NUM_NOISE_INPUTS];
uint8_t *p = buf;
/*
* NUM_NOISE_INPUTS is seven.
*
* There are sixteen bytes in the CRC-16 buffer. We use seven
* outputs of CRC-16 buffer for final output. There are two parts;
* former 4 outputs which will be used directly, and latter 3
* outputs which will be used with feedback loop.
*/
/* At some probability, use latter 3 outputs of CRC-16 buffer */
for (i = NUM_NOISE_INPUTS - 1; i >= 4; i--)
if (PROBABILITY_50_BY_TICK ())
*p++ = epool[(ep_count+i) & 0x0f] ^ epool[(ep_count+i-4) & 0x0f];
/* Use former 4 outputs of CRC-16 buffer */
for (i = 3; i >= 0; i--)
*p++ = epool[(ep_count+i) & 0x0f];
return fnv32_hash (buf, p - buf);
}
/*
* Ring buffer, filled by generator, consumed by neug_get routine.
*/
struct rng_rb {
uint32_t *buf;
Mutex m;
CondVar data_available;
CondVar space_available;
uint8_t head, tail;
uint8_t size;
unsigned int full :1;
unsigned int empty :1;
};
static void rb_init (struct rng_rb *rb, uint32_t *p, uint8_t size)
{
rb->buf = p;
rb->size = size;
chMtxInit (&rb->m);
chCondInit (&rb->data_available);
chCondInit (&rb->space_available);
rb->head = rb->tail = 0;
rb->full = 0;
rb->empty = 1;
}
static void rb_add (struct rng_rb *rb, uint32_t v)
{
rb->buf[rb->tail++] = v;
if (rb->tail == rb->size)
rb->tail = 0;
if (rb->tail == rb->head)
rb->full = 1;
rb->empty = 0;
}
static uint32_t rb_del (struct rng_rb *rb)
{
uint32_t v = rb->buf[rb->head++];
if (rb->head == rb->size)
rb->head = 0;
if (rb->head == rb->tail)
rb->empty = 1;
rb->full = 0;
return v;
}
/**
* @brief Random number generation from ADC sampling.
* @param RB: Pointer to ring buffer structure
* @return -1 when failure, 0 otherwise.
* @note Called holding the mutex, with RB->full == 0.
* Keep generating until RB->full == 1.
*/
static int rng_gen (struct rng_rb *rb)
{
static uint8_t round = 0;
uint8_t b;
while (1)
{
chEvtWaitOne (ADC_DATA_AVAILABLE);
/* Got, ADC sampling data */
round++;
b = (((samp[0] & 0x01) << 0) | ((samp[1] & 0x01) << 1)
| ((samp[2] & 0x01) << 2) | ((samp[3] & 0x01) << 3)
| ((samp[4] & 0x01) << 4) | ((samp[5] & 0x01) << 5)
| ((samp[6] & 0x01) << 6) | ((samp[7] & 0x01) << 7));
adcStartConversion (&ADCD1, &adcgrpcfg, samp, ADC_GRP1_BUF_DEPTH, adccb);
/*
* Put a random byte to entropy pool.
*/
ep_add (b, PROBABILITY_50_BY_TICK ());
if ((round % NUM_NOISE_INPUTS) == 0)
{ /* We have enough entropy in the pool. */
uint32_t v = ep_output (); /* Get the random bits from the pool. */
/* Mix the random bits from the pool with the output of PRNG. */
tmt_one_step ();
v ^= tmt_value ();
/* We got the final random bits, add it to the ring buffer. */
rb_add (rb, v);
round = 0;
if (rb->full)
/* fully generated */
break;
}
}
return 0; /* success */
}
/**
* @brief Random number generation thread.
*/
static msg_t rng (void *arg)
{
struct rng_rb *rb = (struct rng_rb *)arg;
rng_thread = chThdSelf ();
adcStart (&ADCD1, NULL);
adcStartConversion (&ADCD1, &adcgrpcfg, samp, ADC_GRP1_BUF_DEPTH, adccb);
while (1)
{
chMtxLock (&rb->m);
while (rb->full)
chCondWait (&rb->space_available);
rng_gen (rb);
chCondSignal (&rb->data_available);
chMtxUnlock ();
}
return 0;
}
static struct rng_rb the_ring_buffer;
static WORKING_AREA(wa_rng, 128);
/**
* @brief Initialize NeuG.
*/
void
neug_init (uint32_t *buf, uint8_t size)
{
struct rng_rb *rb = &the_ring_buffer;
tmt_init (0);
rb_init (rb, buf, size);
chThdCreateStatic (wa_rng, sizeof (wa_rng), NORMALPRIO, rng, rb);
}
/**
* @breif Flush random bytes.
*/
void
neug_flush (void)
{
struct rng_rb *rb = &the_ring_buffer;
chMtxLock (&rb->m);
while (!rb->empty)
(void)rb_del (rb);
chCondSignal (&rb->space_available);
chMtxUnlock ();
}
/**
* @breif Set seed to PRNG
*/
void
neug_prng_reseed (void)
{
uint32_t seed = ep_output ();
tmt_init (seed);
neug_flush ();
}
/**
* @brief Wakes up RNG thread to generate random numbers.
*/
void
neug_kick_filling (void)
{
struct rng_rb *rb = &the_ring_buffer;
chMtxLock (&rb->m);
if (!rb->full)
chCondSignal (&rb->space_available);
chMtxUnlock ();
}
/**
* @brief Get random word (32-bit) from NeuG.
* @detail With NEUG_KICK_FILLING, it wakes up RNG thread.
* With NEUG_NO_KICK, it doesn't wake up RNG thread automatically,
* it is needed to call neug_kick_filling later.
*/
uint32_t
neug_get (int kick)
{
struct rng_rb *rb = &the_ring_buffer;
uint32_t v;
chMtxLock (&rb->m);
while (rb->empty)
chCondWait (&rb->data_available);
v = rb_del (rb);
if (kick)
chCondSignal (&rb->space_available);
chMtxUnlock ();
return v;
}
void
neug_wait_full (void)
{
struct rng_rb *rb = &the_ring_buffer;
chMtxLock (&rb->m);
while (!rb->full)
chCondWait (&rb->data_available);
chMtxUnlock ();
}

11
src/neug.h Normal file
View File

@@ -0,0 +1,11 @@
#define NEUG_NO_KICK 0
#define NEUG_KICK_FILLING 1
#define NEUG_PRE_LOOP 16
void neug_init (uint32_t *buf, uint8_t size);
void neug_prng_reseed (void);
uint32_t neug_get (int kick);
void neug_kick_filling (void);
void neug_flush (void);
void neug_wait_full (void);

View File

@@ -77,12 +77,11 @@ uint16_t data_objects_number_of_bytes;
static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
10,
0x00,
0x31, 0x80, /* Full DF name */
0x31, 0x84, /* Full DF name, GET DATA, MF */
0x73,
0x80, 0x01, 0x40, /* Full DF name */
0x80, 0x01, 0x80, /* Full DF name */
/* 1-byte */
/* No command chaining */
/* Extended Lc and Le */
/* Command chaining, No extended Lc and Le */
0x00, 0x90, 0x00 /* Status info (no life cycle management) */
};
@@ -90,23 +89,24 @@ static const uint8_t historical_bytes[] __attribute__ ((aligned (1))) = {
static const uint8_t extended_capabilities[] __attribute__ ((aligned (1))) = {
10,
0x30, /*
* No SM, No get challenge,
* No SM,
* No get challenge,
* Key import supported,
* PW status byte can be put,
* No private_use_DO,
* No algo change allowed
*/
0, /* Secure Messaging Algorithm: N/A (TDES=0, AES=1) */
0x00, 0x00, /* Max get challenge */
0x07, 0xfe, /* max. length of cardholder certificate (2KB - 2)*/
/* Max. length of command data */
(MAX_CMD_APDU_SIZE>>8), (MAX_CMD_APDU_SIZE&0xff),
/* Max. length of response data */
#if 0
(MAX_RES_APDU_SIZE>>8), (MAX_RES_APDU_SIZE&0xff),
0x00, 0x00, /* Max get challenge (0: Get challenge not supported) */
#ifdef CERTDO_SUPPORT
0x08, 0x00, /* max. length of cardholder certificate (2KiB) */
#else
0x08, 0x00, /* the case of cardholder ceritificate */
0x00, 0x00,
#endif
/* Max. length of command APDU data */
0x00, 0xff,
/* Max. length of response APDU data */
0x01, 0x00,
};
/* Algorithm Attributes */
@@ -413,10 +413,12 @@ do_kgtime_all (uint16_t tag, int with_tag)
}
const uint8_t openpgpcard_aid[] = {
0xd2, 0x76, 0x00, 0x01, 0x24, 0x01,
0x02, 0x00, /* Version 2.0 */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* To be overwritten */
0xd2, 0x76, /* D: National, 276: DEU ISO 3166-1 */
0x00, 0x01, 0x24, /* Registered Application Provider Identifier */
0x01, /* Application: OpenPGPcard */
0x02, 0x00, /* Version 2.0 */
/* v. id */ /* serial number */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* To be overwritten */
};
static int
@@ -627,6 +629,9 @@ gpg_do_load_prvkey (enum kind_of_key kk, int who, const uint8_t *keystring)
uint8_t dek[DATA_ENCRYPTION_KEY_SIZE];
struct key_data_internal kdi;
DEBUG_INFO ("Loading private key: ");
DEBUG_BYTE (kk);
if (do_data == NULL)
return 0;
@@ -646,6 +651,7 @@ gpg_do_load_prvkey (enum kind_of_key kk, int who, const uint8_t *keystring)
/* more sanity check??? */
memcpy (kd[kk].data, kdi.data, KEY_CONTENT_LEN);
DEBUG_BINARY (&kd[kk], KEY_CONTENT_LEN);
return 1;
}
@@ -835,13 +841,13 @@ gpg_do_chks_prvkey (enum kind_of_key kk,
}
/*
* 4d, xx, xx: Extended Header List
* 4d, xx, xx, xx: Extended Header List
* b6 00 (SIG) / b8 00 (DEC) / a4 00 (AUT)
* 7f48, xx: cardholder private key template
* 91 xx
* 92 xx
* 93 xx
* 5f48, xx: cardholder private key
* 92 xx xx
* 93 xx xx
* 5f48, xx xx xx: cardholder private key
*/
static int
proc_key_import (const uint8_t *data, int len)
@@ -849,6 +855,7 @@ proc_key_import (const uint8_t *data, int len)
int r;
enum kind_of_key kk;
const uint8_t *keystring_admin;
const uint8_t *p = data;
if (admin_authorized == BY_ADMIN)
keystring_admin = keystring_md_pw3;
@@ -857,9 +864,20 @@ proc_key_import (const uint8_t *data, int len)
DEBUG_BINARY (data, len);
if (data[4] == 0xb6)
if (*p++ != 0x4d)
return 0;
/* length field */
if (*p == 0x82)
p += 3;
else if (*p == 0x81)
p += 2;
else
p += 1;
if (*p == 0xb6)
kk = GPG_KEY_FOR_SIGNING;
else if (data[4] == 0xb8)
else if (*p == 0xb8)
kk = GPG_KEY_FOR_DECRYPTION;
else /* 0xa4 */
kk = GPG_KEY_FOR_AUTHENTICATION;
@@ -1237,20 +1255,22 @@ copy_do (const struct do_table_entry *do_p, int with_tag)
void
gpg_do_get_data (uint16_t tag, int with_tag)
{
#if defined(CERTDO_SUPPORT)
if (tag == GPG_DO_CH_CERTIFICATE)
{
res_APDU_pointer = &ch_certificate_start;
res_APDU_size = ((res_APDU_pointer[2] << 8) | res_APDU_pointer[3]);
if (res_APDU_size == 0xffff)
apdu.res_apdu_data = &ch_certificate_start;
apdu.res_apdu_data_len = ((apdu.res_apdu_data[2] << 8) | apdu.res_apdu_data[3]);
if (apdu.res_apdu_data_len == 0xffff)
{
res_APDU_pointer = NULL;
apdu.res_apdu_data_len = 0;
GPG_NO_RECORD ();
}
else
/* Add length of (tag+len) and status word (0x9000) at the end */
res_APDU_size += 4 + 2;
/* Add length of (tag+len) */
apdu.res_apdu_data_len += 4;
}
else
#endif
{
const struct do_table_entry *do_p = get_do_entry (tag);
@@ -1266,9 +1286,8 @@ gpg_do_get_data (uint16_t tag, int with_tag)
GPG_SECURITY_FAILURE ();
else
{
*res_p++ = 0x90;
*res_p++ = 0x00;
res_APDU_size = res_p - res_APDU;
GPG_SUCCESS ();
}
}
else
@@ -1402,8 +1421,8 @@ gpg_do_public_key (uint8_t kk_byte)
*res_p++ = 0x01; *res_p++ = 0x00; *res_p++ = 0x01;
/* Success */
*res_p++ = 0x90; *res_p++ = 0x00;
res_APDU_size = res_p - res_APDU;
GPG_SUCCESS ();
}
DEBUG_INFO ("done.\r\n");

View File

@@ -29,6 +29,11 @@
#include "polarssl/config.h"
#include "polarssl/sha1.h"
#define CLS(a) a.cmd_apdu_head[0]
#define INS(a) a.cmd_apdu_head[1]
#define P1(a) a.cmd_apdu_head[2]
#define P2(a) a.cmd_apdu_head[3]
#define INS_VERIFY 0x20
#define INS_CHANGE_REFERENCE_DATA 0x24
#define INS_PSO 0x2a
@@ -62,11 +67,9 @@ select_file_TOP_result[] __attribute__ ((aligned (1))) = {
};
void
set_res_apdu (uint8_t sw1, uint8_t sw2)
set_res_sw (uint8_t sw1, uint8_t sw2)
{
res_APDU_size = 2;
res_APDU[0] = sw1;
res_APDU[1] = sw2;
apdu.sw = (sw1 << 8) | sw2;
}
#define FILE_NONE 0
@@ -97,24 +100,19 @@ gpg_fini (void)
#if defined(PINPAD_SUPPORT)
/*
* Invoke the thread PIN_MAIN, and let user input PIN string.
* Let user input PIN string.
* Return length of the string.
* The string itself is in PIN_INPUT_BUFFER.
*/
static int
get_pinpad_input (int msg_code)
{
Thread *t;
int r;
t = chThdCreateFromHeap (NULL, THD_WA_SIZE (128),
NORMALPRIO, pin_main, (void *)msg_code);
if (t == NULL)
return -1;
else
{
chThdWait (t);
return pin_input_len;
}
chEvtSignal (main_thread, LED_INPUT_MODE);
r = pinpad_getline (msg_code, MS2ST (8000));
chEvtSignal (main_thread, LED_STATUS_MODE);
return r;
}
#endif
@@ -122,40 +120,15 @@ static void
cmd_verify (void)
{
int len;
uint8_t p2 = cmd_APDU[3];
uint8_t p2 = P2 (apdu);
int r;
int data_start = 5;
const uint8_t *pw;
DEBUG_INFO (" - VERIFY\r\n");
DEBUG_BYTE (p2);
#if defined(PINPAD_SUPPORT)
if (cmd_APDU_size == 4)
/* Verification with pinpad */
{
len = get_pinpad_input (PIN_INPUT_CURRENT);
if (len < 0)
{
GPG_ERROR ();
return;
}
pw = pin_input_buffer;
}
else
#endif
{
len = cmd_APDU[4];
if (len == 0) /* extended length */
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
data_start = 7;
}
pw = &cmd_APDU[data_start];
}
len = apdu.cmd_apdu_data_len;
pw = apdu.cmd_apdu_data;
if (p2 == 0x81)
r = verify_pso_cds (pw, len);
@@ -236,7 +209,8 @@ cmd_change_password (void)
uint8_t old_ks[KEYSTRING_MD_SIZE];
uint8_t new_ks0[KEYSTRING_MD_SIZE+1];
uint8_t *new_ks = &new_ks0[1];
uint8_t p2 = cmd_APDU[3];
uint8_t p1 = P1 (apdu); /* 0: change (old+new), 1: exchange (new) */
uint8_t p2 = P2 (apdu);
int len;
const uint8_t *pw;
const uint8_t *newpw;
@@ -247,62 +221,20 @@ cmd_change_password (void)
DEBUG_INFO ("Change PW\r\n");
DEBUG_BYTE (who);
#if defined(PINPAD_SUPPORT)
if (cmd_APDU_size == 4)
/* Modification with pinpad */
len = apdu.cmd_apdu_data_len;
pw = apdu.cmd_apdu_data;
if (p1 != 0)
{
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
if (pw_len < 0)
{
GPG_ERROR ();
return;
}
pw = &cmd_APDU[5];
memcpy (&cmd_APDU[5], pin_input_buffer, pw_len);
newpw = pw + pw_len;
newpw_len = get_pinpad_input (PIN_INPUT_NEW);
if (newpw_len < 0)
{
GPG_ERROR ();
return;
}
memcpy (&cmd_APDU[5]+pw_len, pin_input_buffer, newpw_len);
len = get_pinpad_input (PIN_INPUT_CONFIRM);
if (len < 0)
{
GPG_ERROR ();
return;
}
if (len != newpw_len || memcmp (newpw, pin_input_buffer, len) != 0)
{
GPG_SECURITY_FAILURE ();
return;
}
len = cmd_APDU[4] = pw_len + newpw_len;
}
else
#endif
{
len = cmd_APDU[4];
pw = &cmd_APDU[5];
if (len == 0) /* extended length */
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
pw += 2;
}
GPG_FUNCTION_NOT_SUPPORTED();
return;
}
if (who == BY_USER) /* PW1 */
{
const uint8_t *ks_pw1 = gpg_do_read_simple (NR_DO_KEYSTRING_PW1);
pw_len = verify_user_0 (pw, len, -1, ks_pw1);
pw_len = verify_user_0 (AC_PSO_CDS_AUTHORIZED, pw, len, -1, ks_pw1);
if (pw_len < 0)
{
@@ -388,7 +320,7 @@ cmd_change_password (void)
static void
cmd_reset_user_password (void)
{
uint8_t p1 = cmd_APDU[2];
uint8_t p1 = P1 (apdu);
int len;
const uint8_t *pw;
const uint8_t *newpw;
@@ -400,61 +332,8 @@ cmd_reset_user_password (void)
DEBUG_INFO ("Reset PW1\r\n");
DEBUG_BYTE (p1);
#if defined(PINPAD_SUPPORT)
if (cmd_APDU_size == 4)
/* Modification with pinpad */
{
if (p1 == 0x00) /* by User with Reseting Code */
{
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
if (pw_len < 0)
{
GPG_ERROR ();
return;
}
memcpy (&cmd_APDU[5], pin_input_buffer, pw_len);
}
else
pw_len = 0;
pw = &cmd_APDU[5];
newpw = pw + pw_len;
newpw_len = get_pinpad_input (PIN_INPUT_NEW);
if (newpw_len < 0)
{
GPG_ERROR ();
return;
}
memcpy (&cmd_APDU[5]+pw_len, pin_input_buffer, newpw_len);
len = get_pinpad_input (PIN_INPUT_CONFIRM);
if (len < 0)
{
GPG_ERROR ();
return;
}
if (len != newpw_len || memcmp (newpw, pin_input_buffer, len) != 0)
{
GPG_SECURITY_FAILURE ();
return;
}
len = cmd_APDU[4] = pw_len + newpw_len;
}
else
#endif
{
len = cmd_APDU[4];
pw = &cmd_APDU[5];
if (len == 0) /* extended length */
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
pw += 2;
}
}
len = apdu.cmd_apdu_data_len;
pw = apdu.cmd_apdu_data;
if (p1 == 0x00) /* by User with Reseting Code */
{
@@ -576,16 +455,9 @@ cmd_put_data (void)
if (file_selection != FILE_DF_OPENPGP)
GPG_NO_RECORD();
tag = ((cmd_APDU[2]<<8) | cmd_APDU[3]);
len = cmd_APDU_size - 5;
data = &cmd_APDU[5];
if (len >= 256)
/* extended Lc */
{
data += 2;
len -= 2;
}
tag = ((P1 (apdu)<<8) | P2 (apdu));
len = apdu.cmd_apdu_data_len;
data = apdu.cmd_apdu_data;
gpg_do_put_data (tag, data, len);
}
@@ -593,16 +465,11 @@ static void
cmd_pgp_gakp (void)
{
DEBUG_INFO (" - Generate Asymmetric Key Pair\r\n");
DEBUG_BYTE (cmd_APDU[2]);
DEBUG_BYTE (P1 (apdu));
if (cmd_APDU[2] == 0x81)
if (P1 (apdu) == 0x81)
/* Get public key */
{
if (cmd_APDU[4] == 0)
gpg_do_public_key (cmd_APDU[7]);
else
gpg_do_public_key (cmd_APDU[5]);
}
gpg_do_public_key (apdu.cmd_apdu_data[0]);
else
{ /* Generate key pair */
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
@@ -620,7 +487,7 @@ cmd_read_binary (void)
if (file_selection == FILE_EF_SERIAL)
{
if (cmd_APDU[3] >= 6)
if (P2 (apdu) >= 6)
GPG_BAD_P0_P1 ();
else
{
@@ -635,16 +502,23 @@ cmd_read_binary (void)
static void
cmd_select_file (void)
{
if (cmd_APDU[2] == 4) /* Selection by DF name: it must be OpenPGP card */
if (P1 (apdu) == 4) /* Selection by DF name */
{
DEBUG_INFO (" - select DF by name\r\n");
/*
* P2 == 0, LC=6, name = D2 76 00 01 24 01
*/
/* name = D2 76 00 01 24 01 */
if (apdu.cmd_apdu_data_len != 6
|| memcmp (openpgpcard_aid, apdu.cmd_apdu_data, 6) != 0)
{
DEBUG_SHORT (apdu.cmd_apdu_data_len);
DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
GPG_NO_FILE ();
return;
}
file_selection = FILE_DF_OPENPGP;
if (cmd_APDU[3] == 0x0c) /* No FCI */
if ((P2 (apdu) & 0x0c) == 0x0c) /* No FCI */
GPG_SUCCESS ();
else
{
@@ -654,10 +528,11 @@ cmd_select_file (void)
res_APDU[1] = 0x12;
res_APDU[2] = 0x84; /* overwrite: DF name */
res_APDU_size += 2;
GPG_SUCCESS ();
}
}
else if (cmd_APDU[4] == 2
&& cmd_APDU[5] == 0x2f && cmd_APDU[6] == 0x02)
else if (apdu.cmd_apdu_data_len == 2
&& apdu.cmd_apdu_data[0] == 0x2f && apdu.cmd_apdu_data[1] == 0x02)
{
DEBUG_INFO (" - select 0x2f02 EF\r\n");
/*
@@ -666,11 +541,11 @@ cmd_select_file (void)
GPG_SUCCESS ();
file_selection = FILE_EF_SERIAL;
}
else if (cmd_APDU[4] == 2
&& cmd_APDU[5] == 0x3f && cmd_APDU[6] == 0x00)
else if (apdu.cmd_apdu_data_len == 2
&& apdu.cmd_apdu_data[0] == 0x3f && apdu.cmd_apdu_data[1] == 0x00)
{
DEBUG_INFO (" - select ROOT MF\r\n");
if (cmd_APDU[3] == 0x0c)
if (P2 (apdu) == 0x0c)
{
GPG_SUCCESS ();
}
@@ -678,12 +553,11 @@ cmd_select_file (void)
{
int len = sizeof (select_file_TOP_result);
res_APDU_size = 2 + len;
res_APDU_size = len;
memcpy (res_APDU, select_file_TOP_result, len);
res_APDU[2] = (data_objects_number_of_bytes & 0xff);
res_APDU[3] = (data_objects_number_of_bytes >> 8);
res_APDU[len] = 0x90;
res_APDU[len+1] = 0x00;
GPG_SUCCESS ();
}
file_selection = FILE_MF;
@@ -701,7 +575,7 @@ cmd_select_file (void)
static void
cmd_get_data (void)
{
uint16_t tag = ((cmd_APDU[2]<<8) | cmd_APDU[3]);
uint16_t tag = ((P1 (apdu)<<8) | P2 (apdu));
DEBUG_INFO (" - Get Data\r\n");
@@ -714,20 +588,14 @@ cmd_get_data (void)
static void
cmd_pso (void)
{
int len = cmd_APDU[4];
int data_start = 5;
int len = apdu.cmd_apdu_data_len;
int r;
if (len == 0)
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
data_start = 7;
}
DEBUG_INFO (" - PSO: ");
DEBUG_WORD ((uint32_t)&r);
DEBUG_BINARY (apdu.cmd_apdu_data, apdu.cmd_apdu_data_len);
if (cmd_APDU[2] == 0x9e && cmd_APDU[3] == 0x9a)
if (P1 (apdu) == 0x9e && P2 (apdu) == 0x9a)
{
if (!ac_check_status (AC_PSO_CDS_AUTHORIZED))
{
@@ -736,23 +604,24 @@ cmd_pso (void)
return;
}
if (cmd_APDU_size != 7 + 34 + 2 /* MD5 */
/* Header (with Extended Lc)=7, size of digestInfo, and Le=2-byte */
&& cmd_APDU_size != 7 + 35 + 2 /* SHA1 / RIPEMD-160 */
&& cmd_APDU_size != 7 + 47 + 2 /* SHA224 */
&& cmd_APDU_size != 7 + 51 + 2 /* SHA256 */
&& cmd_APDU_size != 7 + 67 + 2 /* SHA384 */
&& cmd_APDU_size != 7 + 83 + 2) /* SHA512 */
/* Check size of digestInfo */
if (len != 34 /* MD5 */
&& len != 35 /* SHA1 / RIPEMD-160 */
&& len != 47 /* SHA224 */
&& len != 51 /* SHA256 */
&& len != 67 /* SHA384 */
&& len != 83) /* SHA512 */
{
DEBUG_INFO (" wrong length: ");
DEBUG_SHORT (cmd_APDU_size);
DEBUG_SHORT (len);
GPG_ERROR ();
}
else
{
DEBUG_SHORT (len); /* Should be cmd_APDU_size - 8 [- 1] */
DEBUG_SHORT (len);
DEBUG_BINARY (&kd[GPG_KEY_FOR_SIGNING], KEY_CONTENT_LEN);
r = rsa_sign (&cmd_APDU[data_start], res_APDU, len,
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
&kd[GPG_KEY_FOR_SIGNING]);
if (r < 0)
{
@@ -764,9 +633,10 @@ cmd_pso (void)
gpg_increment_digital_signature_counter ();
}
}
else if (cmd_APDU[2] == 0x80 && cmd_APDU[3] == 0x86)
else if (P1 (apdu) == 0x80 && P2 (apdu) == 0x86)
{
DEBUG_SHORT (len);
DEBUG_BINARY (&kd[GPG_KEY_FOR_DECRYPTION], KEY_CONTENT_LEN);
if (!ac_check_status (AC_OTHER_AUTHORIZED))
{
@@ -776,9 +646,8 @@ cmd_pso (void)
}
/* Skip padding 0x00 */
data_start++;
len--;
r = rsa_decrypt (&cmd_APDU[data_start], res_APDU, len,
r = rsa_decrypt (apdu.cmd_apdu_data+1, res_APDU, len,
&kd[GPG_KEY_FOR_DECRYPTION]);
if (r < 0)
GPG_ERROR ();
@@ -786,9 +655,9 @@ cmd_pso (void)
else
{
DEBUG_INFO (" - ??");
DEBUG_BYTE (cmd_APDU[2]);
DEBUG_BYTE (P1 (apdu));
DEBUG_INFO (" - ??");
DEBUG_BYTE (cmd_APDU[3]);
DEBUG_BYTE (P2 (apdu));
GPG_ERROR ();
}
@@ -798,19 +667,12 @@ cmd_pso (void)
static void
cmd_internal_authenticate (void)
{
int len = cmd_APDU[4];
int data_start = 5;
int len = apdu.cmd_apdu_data_len;
int r;
if (len == 0)
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
data_start = 7;
}
DEBUG_INFO (" - INTERNAL AUTHENTICATE\r\n");
if (cmd_APDU[2] == 0x00 && cmd_APDU[3] == 0x00)
if (P1 (apdu) == 0x00 && P2 (apdu) == 0x00)
{
DEBUG_SHORT (len);
@@ -821,7 +683,7 @@ cmd_internal_authenticate (void)
return;
}
r = rsa_sign (&cmd_APDU[data_start], res_APDU, len,
r = rsa_sign (apdu.cmd_apdu_data, res_APDU, len,
&kd[GPG_KEY_FOR_AUTHENTICATION]);
if (r < 0)
GPG_ERROR ();
@@ -829,9 +691,9 @@ cmd_internal_authenticate (void)
else
{
DEBUG_INFO (" - ??");
DEBUG_BYTE (cmd_APDU[2]);
DEBUG_BYTE (P1 (apdu));
DEBUG_INFO (" - ??");
DEBUG_BYTE (cmd_APDU[3]);
DEBUG_BYTE (P2 (apdu));
GPG_ERROR ();
}
@@ -842,17 +704,10 @@ cmd_internal_authenticate (void)
static void
cmd_update_binary (void)
{
int len = cmd_APDU[4];
int data_start = 5;
int len = apdu.cmd_apdu_data_len;
uint16_t offset;
int r;
if (len == 0)
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
data_start = 7;
}
DEBUG_INFO (" - UPDATE BINARY\r\n");
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
@@ -862,10 +717,10 @@ cmd_update_binary (void)
return;
}
if ((cmd_APDU[2] & 0x80))
if ((cmd_APDU[2] & 0x7f) <= FILEID_RANDOM)
if ((P1 (apdu) & 0x80))
if ((P1 (apdu) & 0x7f) <= FILEID_RANDOM)
{
file_selection = FILE_EF_CH_CERTIFICATE + (cmd_APDU[2] & 0x7f);
file_selection = FILE_EF_CH_CERTIFICATE + (P1 (apdu) & 0x7f);
r = flash_erase_binary (file_selection - FILE_EF_CH_CERTIFICATE);
if (r < 0)
{
@@ -890,14 +745,14 @@ cmd_update_binary (void)
return;
}
offset = (cmd_APDU[2] << 8) | cmd_APDU[3];
offset = (P1 (apdu) << 8) | P2 (apdu);
}
DEBUG_SHORT (len);
DEBUG_SHORT (offset);
r = flash_write_binary (file_selection - FILE_EF_CH_CERTIFICATE,
&cmd_APDU[data_start], len, offset);
apdu.cmd_apdu_data, len, offset);
if (r < 0)
{
DEBUG_INFO ("memory error.\r\n");
@@ -913,17 +768,10 @@ cmd_update_binary (void)
static void
cmd_write_binary (void)
{
int len = cmd_APDU[4];
int data_start = 5;
int len = apdu.cmd_apdu_data_len;
uint16_t offset;
int r;
if (len == 0)
{
len = (cmd_APDU[5]<<8) | cmd_APDU[6];
data_start = 7;
}
DEBUG_INFO (" - WRITE BINARY\r\n");
if (!ac_check_status (AC_ADMIN_AUTHORIZED))
@@ -933,10 +781,10 @@ cmd_write_binary (void)
return;
}
if ((cmd_APDU[2] & 0x80))
if ((cmd_APDU[2] & 0x7f) <= FILEID_SERIAL_NO)
if ((P1 (apdu) & 0x80))
if ((P1 (apdu) & 0x7f) <= FILEID_SERIAL_NO)
{
file_selection = FILE_EF_CH_CERTIFICATE + (cmd_APDU[2] & 0x7f);
file_selection = FILE_EF_CH_CERTIFICATE + (P1 (apdu) & 0x7f);
offset = 0;
}
else
@@ -954,14 +802,14 @@ cmd_write_binary (void)
return;
}
offset = (cmd_APDU[2] << 8) | cmd_APDU[3];
offset = (P1 (apdu) << 8) | P2 (apdu);
}
DEBUG_SHORT (len);
DEBUG_SHORT (offset);
r = flash_write_binary (file_selection - FILE_EF_CH_CERTIFICATE,
&cmd_APDU[data_start], len, offset);
apdu.cmd_apdu_data, len, offset);
if (r < 0)
{
DEBUG_INFO ("memory error.\r\n");
@@ -1001,7 +849,7 @@ static void
process_command_apdu (void)
{
int i;
uint8_t cmd = cmd_APDU[1];
uint8_t cmd = INS (apdu);
for (i = 0; i < NUM_CMDS; i++)
if (cmds[i].command == cmd)
@@ -1028,20 +876,99 @@ GPGthread (void *arg)
while (!chThdShouldTerminate ())
{
eventmask_t m;
m = chEvtWaitOne (ALL_EVENTS);
eventmask_t m = chEvtWaitOne (ALL_EVENTS);
#if defined(PINPAD_SUPPORT)
int len, pw_len, newpw_len;
#endif
DEBUG_INFO ("GPG!: ");
DEBUG_WORD ((uint32_t)&m);
res_APDU_pointer = NULL; /* default */
if (icc_data_size != 0)
if (m == EV_VERIFY_CMD_AVAILABLE)
{
process_command_apdu ();
chEvtSignal (icc_thread, EV_EXEC_FINISHED);
#if defined(PINPAD_SUPPORT)
if (INS (apdu) != INS_VERIFY)
{
GPG_CONDITION_NOT_SATISFIED ();
goto done;
}
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
if (pw_len < 0)
{
GPG_ERROR ();
goto done;
}
memcpy (apdu.cmd_apdu_data, pin_input_buffer, pw_len);
apdu.cmd_apdu_data_len = pw_len;
#else
GPG_ERROR ();
goto done;
#endif
}
else if (m == EV_MODIFY_CMD_AVAILABLE)
{
#if defined(PINPAD_SUPPORT)
uint8_t bConfirmPIN = apdu.cmd_apdu_data[5];
uint8_t *p = apdu.cmd_apdu_data;
if (INS (apdu) != INS_CHANGE_REFERENCE_DATA
&& INS (apdu) != INS_RESET_RETRY_COUNTER
&& INS (apdu) != INS_PUT_DATA)
{
GPG_CONDITION_NOT_SATISFIED ();
goto done;
}
if ((bConfirmPIN & 2)) /* Require old PIN */
{
pw_len = get_pinpad_input (PIN_INPUT_CURRENT);
if (pw_len < 0)
{
GPG_ERROR ();
goto done;
}
memcpy (p, pin_input_buffer, pw_len);
p += pw_len;
}
else
pw_len = 0;
newpw_len = get_pinpad_input (PIN_INPUT_NEW);
if (newpw_len < 0)
{
GPG_ERROR ();
goto done;
}
memcpy (p, pin_input_buffer, newpw_len);
if ((bConfirmPIN & 1)) /* New PIN twice */
{
len = get_pinpad_input (PIN_INPUT_CONFIRM);
if (len < 0)
{
GPG_ERROR ();
goto done;
}
if (len != newpw_len || memcmp (p, pin_input_buffer, len) != 0)
{
GPG_SECURITY_FAILURE ();
goto done;
}
}
apdu.cmd_apdu_data_len = pw_len + newpw_len;
#else
GPG_ERROR ();
goto done;
#endif
}
else if (m == EV_NOP)
continue;
process_command_apdu ();
done:
chEvtSignal (icc_thread, EV_EXEC_FINISHED);
}
gpg_fini ();

View File

@@ -1,10 +1,12 @@
#define GPG_MEMORY_FAILURE() set_res_apdu (0x65, 0x81)
#define GPG_SECURITY_FAILURE() set_res_apdu (0x69, 0x82)
#define GPG_SECURITY_AUTH_BLOCKED() set_res_apdu (0x69, 0x83)
#define GPG_COMMAND_NOT_ALLOWED() set_res_apdu (0x69, 0x86)
#define GPG_NO_FILE() set_res_apdu (0x6a, 0x82)
#define GPG_NO_RECORD() set_res_apdu (0x6a, 0x88)
#define GPG_BAD_P0_P1() set_res_apdu (0x6b, 0x00)
#define GPG_NO_INS() set_res_apdu (0x6d, 0x00)
#define GPG_ERROR() set_res_apdu (0x6f, 0x00)
#define GPG_SUCCESS() set_res_apdu (0x90, 0x00)
#define GPG_MEMORY_FAILURE() set_res_sw (0x65, 0x81)
#define GPG_SECURITY_FAILURE() set_res_sw (0x69, 0x82)
#define GPG_SECURITY_AUTH_BLOCKED() set_res_sw (0x69, 0x83)
#define GPG_CONDITION_NOT_SATISFIED() set_res_sw (0x69, 0x85)
#define GPG_COMMAND_NOT_ALLOWED() set_res_sw (0x69, 0x86)
#define GPG_FUNCTION_NOT_SUPPORTED() set_res_sw (0x6a, 0x81)
#define GPG_NO_FILE() set_res_sw (0x6a, 0x82)
#define GPG_NO_RECORD() set_res_sw (0x6a, 0x88)
#define GPG_BAD_P0_P1() set_res_sw (0x6b, 0x00)
#define GPG_NO_INS() set_res_sw (0x6d, 0x00)
#define GPG_ERROR() set_res_sw (0x6f, 0x00)
#define GPG_SUCCESS() set_res_sw (0x90, 0x00)

View File

@@ -27,13 +27,41 @@
#include "board.h"
#include "gnuk.h"
#if 0
#ifdef DEBUG
#define DEBUG_CIR 1
#endif
uint8_t pin_input_buffer[MAX_PIN_CHARS];
uint8_t pin_input_len;
/*
* Supported/tested TV controllers:
*
* Controller of Toshiba REGZA
* Controller of Sony BRAVIA
* Controller of Sharp AQUOS
* Dell Wireless Travel Remote MR425
*
* The code supports RC-5 protocol in fact, but I don't have any
* controller at hand which I can test with, so I don't have any data
* for controller of RC-5.
*
* Current code assumes following mapping:
*
* --------------------------------------
* Protocol Controller
* --------------------------------------
* RC-6 Dell MR425
* NEC Toshiba REGZA
* Sharp Sharp AQUOS
* Sony Sony BRAVIA
* --------------------------------------
*
* In future, when I will have other controllers, this mapping will be
* (should be) configurable, at compile time at least, preferably at
* runtime.
*/
/*
* Philips RC-5 Protocol: 14-bit (MSB first)
*
@@ -69,18 +97,26 @@ uint8_t pin_input_len;
*/
/*
* PB0 / TIM3_CH3
* The implementation note of CIR signal decoding (on STM32).
*
* (1) Use EXTI interrupt to detect the first edge of signal.
* (2) Use Timer (with PWM input mode) to measure timings of square wave.
*
*/
/*
* Timer settings.
*
* See THE reference manual (RM0008) section 15.3.6 PWM input mode.
*
* 72MHz
*
* Prescaler = 72
*
* 1us
*
*
* TIM3_CR1
* CKD = 10 (sampling x4)
* ARPE = 0 (not buffered)
* TIMx_CR1
* CKD = 00 (tDTS = tCK_INT)
* ARPE = 1 (buffered)
* CMS = 00 (up counter)
* DIR = 0 (up counter)
* OPM = 0 (up counter)
@@ -88,13 +124,13 @@ uint8_t pin_input_len;
* UDIS = 0 (UEV (update event) enabled)
* CEN = 1 (counter enable)
*
* TIM3_CR2
* TIMx_CR2
* TI1S = 1 (TI1 is XOR of ch1, ch2, ch3)
* MMS = 000 (TRGO at Reset)
* CCDS = 0 (DMA on capture)
* RSVD = 000
*
* TIM3_SMCR
* TIMx_SMCR
* ETP = 0
* ECE = 0
* ETPS = 00
@@ -104,61 +140,37 @@ uint8_t pin_input_len;
* RSVD = 0
* SMS = 100 (Reset-mode)
*
* TIM3_DIER
* TIMx_DIER
*
* TIM3_SR
* TIMx_SR
*
* TIM3_EGR
* TIMx_EGR
*
* TIM3_CCMR1
* TIMx_CCMR1
* CC1S = 01 (TI1 selected)
* CC2S = 10 (TI1 selected)
* IC1F = 1001 (fSAMPLING=fDTS/8, N=8)
* IC2F = 1001 (fSAMPLING=fDTS/8, N=8)
*
* TIM3_CCMR2
* TIMx_CCMR2
*
* TIM3_CCER
* TIMx_CCER
* CC2P = 1 (polarity = falling edge: TI1FP1)
* CC2E = 1
* CC1P = 0 (polarity = rising edge: TI1FP1)
* CC1E = 1
*
* TIM3_CNT
* TIM3_PSC = 71
* TIM3_ARR = 18000
* TIMx_CNT
* TIMx_PSC = 71
* TIMx_ARR = 18000
*
* TIM3_CCR1 period
* TIM3_CCR2 duty
* TIMx_CCR1 period
* TIMx_CCR2 duty
*
* TIM3_DCR
* TIM3_DMAR
* TIMx_DCR
* TIMx_DMAR
*/
#define PINDISP_TIMEOUT_INTERVAL0 MS2ST(25)
#define PINDISP_TIMEOUT_INTERVAL1 MS2ST(300)
static void
pindisp (uint8_t c)
{
#if defined(HAVE_7SEGLED)
switch (c)
{
case 'G':
palWritePort (IOPORT2, 0xa1ff);
break;
case 'P':
palWritePort (IOPORT2, 0x98ff);
break;
case '.':
palWritePort (IOPORT2, 0x7fff);
break;
default:
palWritePort (IOPORT2, 0xffff);
}
#else
(void)c;
#endif
}
#if defined(DEBUG_CIR)
static uint16_t intr_ext;
static uint16_t intr_trg;
@@ -179,14 +191,6 @@ static uint8_t cir_proto;
#define CIR_PROTO_NEC 5
#define CIR_PROTO_SHARP 6
#define CIR_KEY_RC6_ENTER 0x0d /* Mute */
#define CIR_KEY_RC6_BACKSPACE 0xa4 /* <= */
#define CIR_KEY_NEC_ENTER 0x3d /* 'kettei' */
#define CIR_KEY_NEC_BACKSPACE 0x3b /* 'modoru' */
#define CIR_KEY_SONY_ENTER 0x65 /* 'kettei' */
#define CIR_KEY_SONY_BACKSPACE 0xa3 /* 'modoru' */
#define CIR_KEY_SHARP_ENTER 0x0252 /* 'kettei' */
#define CIR_KEY_SHARP_BACKSPACE 0xe4 /* 'modoru' */
/* CIR_DATA_ZERO: Used for zero-bit handling of RC-5/RC-6 */
static uint8_t cir_data_zero;
@@ -196,6 +200,388 @@ static uint8_t cir_seq;
static systime_t cir_input_last;
#define CIR_PERIOD_INHIBIT_CHATTER 200 /* mili second */
static void
cir_init (void)
{
cir_data = 0;
cir_seq = 0;
/* Don't touch cir_proto here */
cir_ext_enable ();
}
#define CH_RETURN 0x0d
#define CH_BACKSPACE 0x08
struct codetable {
uint16_t cir_code;
uint8_t char_code;
};
/* NOTE: no way to input '0' */
static const struct codetable
cir_codetable_dell_mr425[] = {
{0x10, '7' }, /* Speaker Louder */
{0x11, '8' }, /* Speaker Quieter */
{0x0d, '9' }, /* Speaker Mute */
{0xce, 'a' }, /* Black triangle UP */
{0xcf, 'b' }, /* Black triangle DOWN */
{0x58, 'c' }, /* White triangle UP */
{0x5a, 'd' }, /* White triangle LEFT */
{0x5c, CH_RETURN }, /* Check */
{0x5b, 'e' }, /* White triangle RIGHT */
{0xa4, CH_BACKSPACE }, /* Back */
{0x59, 'f' }, /* White triangle DOWN */
{0x2f, '1' }, /* Rewind */
{0x2c, '2' }, /* Play / Pause */
{0x2e, '3' }, /* Forward */
{0x21, '4' }, /* Skip backward */
{0x31, '5' }, /* Stop */
{0x20, '6' }, /* Skip forward */
{0, 0} /* <<END>> */
};
#define CIR_ADDR_SHARP_AQUOS 0x028f
static const struct codetable
cir_codetable_aquos[] = {
{ 0x0116, ' ' }, /* Power */
{ 0x025e, '0' }, /* d */
{ 0x024e, '1' }, /* 1 */
{ 0x024f, '2' }, /* 2 */
{ 0x0250, '3' }, /* 3 */
{ 0x0251, '4' }, /* 4 */
{ 0x0252, '5' }, /* 5 */
{ 0x0253, '6' }, /* 6 */
{ 0x0254, '7' }, /* 7 */
{ 0x0255, '8' }, /* 8 */
{ 0x0256, '9' }, /* 9 */
{ 0x0257, 'a' }, /* 10/0 */
{ 0x0258, 'b' }, /* 11 */
{ 0x0259, 'c' }, /* 12 */
{ 0x0111, 'd' }, /* Ch ^ */
{ 0x0112, 'e' }, /* Ch v */
{ 0x0114, 'f' }, /* Vol + */
{ 0x0115, 'g' }, /* Vol - */
{ 0x0117, 'h' }, /* Mute */
{ 0x0280, 'i' }, /* BLUE */
{ 0x0281, 'j' }, /* RED */
{ 0x0282, 'k' }, /* GREEN */
{ 0x0283, 'l' }, /* YELLOW */
{ 0x011b, 'm' }, /* DISPLAY CONTROL (gamen hyouji) */
{ 0x01d5, 'n' }, /* DISPLAY SIZE */
{ 0x0157, 'o' }, /* UP */
{ 0x01d7, 'p' }, /* LEFT */
{ 0x01d8, 'q' }, /* RIGHT */
{ 0x0120, 'r' }, /* DOWN */
{ 0x0152, CH_RETURN }, /* Commit (kettei) */
{ 0x01e4, CH_BACKSPACE }, /* Back (modoru) */
{ 0x01f5, 's' }, /* Quit (shuuryou) */
{ 0x0b03, 't' }, /* Rewind (hayamodoshi) */
{ 0x0b01, 'u' }, /* Play (saisei) */
{ 0x0b04, 'v' }, /* Forward (hayaokuri) */
{ 0x0b02, 'w' }, /* Stop (teishi) */
{ 0x028a, 'x' }, /* BS */
{ 0x028b, 'y' }, /* CS */
{ 0x025f, 'z' }, /* Program information (bangumi jouhou) */
{ 0x0260, '\\' }, /* Program table (bangumi hyou) */
{ 0x0118, '|' }, /* Sound channel (onsei kirikae) */
{ 0x028e, '[' }, /* Ground Analog (chijou A) */
{ 0x0289, ']' }, /* Ground Digital (chijou D) */
{ 0x0b07, '\"' }, /* Feature select (kinou sentaku) */
{ 0x026b, '.' }, /* TV/Radio/Data (terebi/rajio/data) */
{ 0x025a, ',' }, /* 3 code input (3 keta nyuuryoku) */
{ 0x0267, ':' }, /* subtitle (jimaku) */
{ 0x0159, ';' }, /* hold (seishi) */
{ 0x01c4, 'A' }, /* Menu */
{ 0x011a, 'B' }, /* Off timer */
{ 0x0121, 'C' }, /* CATV */
{ 0x0b05, 'D' }, /* Record */
{ 0x0b06, 'E' }, /* Recording stop */
{ 0x0113, 'F' }, /* Inputs (nyuuryoku kirikae) */
{ 0x0275, 'G' }, /* other programs (ura bangumi) */
{ 0x0266, 'H' }, /* signal control (eizou kirikae) */
{ 0x01e7, 'I' }, /* AV position */
{ 0x027f, 'J' }, /* i.LINK */
{ 0x0b00, 'K' }, /* Recorder power */
{ 0x028f, 'L' }, /* as you like it (okonomi senkyoku) */
{0, 0} /* <<END>> */
};
#define CIR_ADDR_TOSHIBA_REGZA 0xbf40
static const struct codetable
cir_codetable_regza[] = {
{ 0x12, ' ' }, /* Power */
{ 0x14, '0' }, /* d (data) */
{ 0x01, '1' }, /* 1 */
{ 0x02, '2' }, /* 2 */
{ 0x03, '3' }, /* 3 */
{ 0x04, '4' }, /* 4 */
{ 0x05, '5' }, /* 5 */
{ 0x06, '6' }, /* 6 */
{ 0x07, '7' }, /* 7 */
{ 0x08, '8' }, /* 8 */
{ 0x09, '9' }, /* 9 */
{ 0x0a, 'a' }, /* 10 */
{ 0x0b, 'b' }, /* 11 */
{ 0x0c, 'c' }, /* 12 */
{ 0x1b, 'd' }, /* Ch ^ */
{ 0x1f, 'e' }, /* Ch v */
{ 0x1a, 'f' }, /* Vol + */
{ 0x1e, 'g' }, /* Vol - */
{ 0x10, 'h' }, /* Mute */
{ 0x73, 'i' }, /* BLUE */
{ 0x74, 'j' }, /* RED */
{ 0x75, 'k' }, /* GREEN */
{ 0x76, 'l' }, /* YELLOW */
{ 0x1c, 'm' }, /* Display control */
{ 0x2b, 'n' }, /* Display size */
{ 0x3e, 'o' }, /* UP */
{ 0x5f, 'p' }, /* LEFT */
{ 0x5b, 'q' }, /* RIGHT */
{ 0x3f, 'r' }, /* DOWN */
{ 0x3d, CH_RETURN }, /* Commit (kettei) */
{ 0x3b, CH_BACKSPACE }, /* Back (modoru) */
{ 0x3c, 's' }, /* Quit (shuuryou) */
{ 0x2c, 't' }, /* << (Rewind) */
{ 0x2d, 'u' }, /* >/|| (Play/Stop) */
{ 0x2e, 'v' }, /* >> (Forward) */
{ 0x2b, 'w' }, /* Stop (teishi) */
{ 0x7c, 'x' }, /* BS */
{ 0x7d, 'y' }, /* CS */
{ 0x71, 'z' }, /* Program information (bangumi setsumei) */
{ 0x77, '\\' }, /* Mini program table (mini bangumihyou) */
{ 0x13, '|' }, /* Sound (onta kirikae) */
{ 0x7a, '[' }, /* Ground Digital (chideji) */
{ 0x7b, ']' }, /* Ground Analog (chiana) */
{ 0xd0, '\"' }, /* Settings Menu (settei menu) */
{ 0x6d, '.' }, /* Radio/Data (rajio/data) */
{ 0x60, ',' }, /* CH 10-key input (search) */
{ 0x52, ':' }, /* subtitle (jimaku) */
{ 0x50, ';' }, /* hold (seishi) */
{ 0x3a, 'A' }, /* Input- (nyuuryokukirikae-) */
{ 0x0f, 'B' }, /* Input+ (nyuuryokukirikae+) */
{ 0x29, 'C' }, /* Two screens (nigamen) */
{ 0x25, 'D' }, /* Broadband */
{ 0x27, 'E' }, /* |<< Skip backward */
{ 0x26, 'F' }, /* >>| Skip forward */
{ 0x61, '!' }, /* 1 NHK1 */
{ 0x62, '@' }, /* 2 NHK2 */
{ 0x63, '#' }, /* 3 NHKh */
{ 0x64, '$' }, /* 4 BS Nihon TV */
{ 0x65, '%' }, /* 5 BS Asahi */
{ 0x66, '^' }, /* 6 BS-i */
{ 0x67, '&' }, /* 7 BSJ */
{ 0x68, '*' }, /* 8 BS Fuji */
{ 0x69, '(' }, /* 9 WOW */
{ 0x6a, ')' }, /* 10 Star */
{ 0x6b, '-' }, /* 11 BS11 */
{ 0x6c, '+' }, /* 12 TwellV */
{ 0x27, '=' }, /* Quick (Delete) */
{ 0x34, '<' }, /* REGZA link */
{ 0x6e, '>' }, /* Program Table */
{ 0x20, '/' }, /* ^^ */
{ 0x22, '\'' }, /* << */
{ 0x23, '?' }, /* >> */
{ 0x21, '_' }, /* vv */
{0, 0} /* <<END>> */
};
static const struct codetable
cir_codetable_bravia[] = {
{ 0x15, ' ' }, /* Power */
{ 0x95, '0' }, /* d (16-bit: 0x4b) */
{ 0x00, '1' }, /* 1 */
{ 0x01, '2' }, /* 2 */
{ 0x02, '3' }, /* 3 */
{ 0x03, '4' }, /* 4 */
{ 0x04, '5' }, /* 5 */
{ 0x05, '6' }, /* 6 */
{ 0x06, '7' }, /* 7 */
{ 0x07, '8' }, /* 8 */
{ 0x08, '9' }, /* 9 */
{ 0x09, 'a' }, /* 10 */
{ 0x0a, 'b' }, /* 11 */
{ 0x0b, 'c' }, /* 12 */
{ 0x10, 'd' }, /* CH+ */
{ 0x11, 'd' }, /* CH- */
{ 0x12, 'f' }, /* Vol+ */
{ 0x13, 'g' }, /* Vol- */
{ 0x14, 'h' }, /* Mute */
{ 0xa4, 'i' }, /* BLUE (16-bit: 0x4b) */
{ 0xa5, 'j' }, /* RED (16-bit: 0x4b) */
{ 0xa6, 'k' }, /* GREEN (16-bit: 0x4b) */
{ 0xa7, 'l' }, /* YELLOW (16-bit: 0x4b) */
{ 0x3a, 'm' }, /* DISPLAY control (gamen hyouji) */
{ 0x3d, 'n' }, /* Display Wide (waido kirikae) */
{ 0x74, 'o' }, /* UP */
{ 0x75, 'p' }, /* DOWN */
{ 0x33, 'q' }, /* RIGHT */
{ 0x34, 'r' }, /* LEFT */
{ 0x65, CH_RETURN }, /* Commit (kettei) */
{ 0xa3, CH_BACKSPACE }, /* Back (modoru) (16-bit: 0x4b) */
{ 0xac, 's' }, /* BS (16-bit: 0x4b) */
{ 0xab, 't' }, /* CS (16-bit: 0x4b) */
{ 0x5b, 'u' }, /* Program table (bangumi hyou) (16-bit: 0x52) */
{ 0x17, 'v' }, /* Sound channel (onsei kirikae) */
{ 0xa8, 'w' }, /* subtitle (jimaku) (16-bit: 0x4b) */
{ 0x5c, 'x' }, /* hold (memo) */
{ 0xb6, 'y' }, /* Tool (16-bit: 0x4b) */
{ 0x8c, 'z' }, /* 10 key input (10ki-) (16-bit: 0x4b) */
{ 0x60, '!' }, /* Menu */
{ 0xae, '@' }, /* Analog (16-bit: 0x4b) */
{ 0xb2, '#' }, /* Digital (16-bit: 0x4b) */
{ 0x25, '$' }, /* Input (nyuuryoku kirikae) */
{0, 0} /* <<END>> */,
};
static int
ch_is_backspace (int ch)
{
return ch == CH_BACKSPACE;
}
static int
ch_is_enter (int ch)
{
return ch == CH_RETURN;
}
/* liner search is good enough for this small amount of data */
static uint8_t
find_char_codetable (uint32_t cir_code, const struct codetable *ctp)
{
while (ctp->cir_code != 0x0000 || ctp->char_code != 0x00)
if (ctp->cir_code == cir_code)
return ctp->char_code;
else
ctp++;
/* Not found */
return cir_code & 0xff;
}
static int
hex (int x)
{
if (x < 10)
return x + '0';
else
return (x - 10) + 'a';
}
static int
cir_getchar (systime_t timeout)
{
uint16_t cir_addr;
eventmask_t m;
#if defined(DEBUG_CIR)
uint16_t *p;
#endif
#if defined(DEBUG_CIR)
cirinput_p = cirinput;
#endif
chEvtClear (ALL_EVENTS);
cir_init ();
m = chEvtWaitOneTimeout (ALL_EVENTS, timeout);
if (m == 0)
return -1;
#if defined(DEBUG_CIR)
DEBUG_INFO ("****\r\n");
DEBUG_SHORT (intr_ext);
DEBUG_SHORT (intr_trg);
DEBUG_SHORT (intr_ovf);
DEBUG_INFO ("----\r\n");
for (p = cirinput; p < cirinput_p; p++)
DEBUG_SHORT (*p);
DEBUG_INFO ("====\r\n");
cirinput_p = cirinput;
DEBUG_INFO ("**** CIR data:");
DEBUG_WORD (cir_data);
if (cir_seq > 48)
DEBUG_SHORT (cir_data_more);
DEBUG_BYTE (cir_seq);
#endif
switch (cir_proto)
{
case CIR_PROTO_RC5:
cir_data &= 0x003f;
goto err;
case CIR_PROTO_RC6:
cir_addr = cir_data >> 8; /* in case of cir_seq == 16. 32??? */
cir_data &= 0x00ff;
return find_char_codetable (cir_data, cir_codetable_dell_mr425);
case CIR_PROTO_NEC:
cir_addr = cir_data&0xffff;
if (cir_addr == CIR_ADDR_TOSHIBA_REGZA)
{
cir_data = (cir_data >> 16) & 0x00ff;
return find_char_codetable (cir_data, cir_codetable_regza);
}
else
goto err;
case CIR_PROTO_SHARP:
cir_addr = cir_data&0x0fff;
if (cir_addr == CIR_ADDR_SHARP_AQUOS)
{
cir_data = (cir_data>>16)&0x0fff;
return find_char_codetable (cir_data, cir_codetable_aquos);
}
else
goto err;
case CIR_PROTO_SONY:
/* Remove ADDRESS bits and filter COMMAND bits */
if (cir_seq == 1 + 12)
{
cir_addr = cir_data >> 7;
cir_data = cir_data & 0x007f;
/* ADDRESS = 0x01 (5-bit) */
}
else
{
cir_addr = cir_data >> 8;
cir_data = cir_data & 0x00ff;
/* ADDRESS = 0x4b or 0x52 (7-bit) */
}
return find_char_codetable (cir_data, cir_codetable_bravia);
err:
default:
/* encode debug information */
pin_input_len = 16;
pin_input_buffer[0] = hex (cir_proto >> 4);
pin_input_buffer[1] = hex (cir_proto & 0x0f);
pin_input_buffer[2] = ':';
pin_input_buffer[3] = hex ((cir_data >> 28) & 0x0f);
pin_input_buffer[4] = hex ((cir_data >> 24) & 0x0f);
pin_input_buffer[5] = hex ((cir_data >> 20) & 0x0f);
pin_input_buffer[6] = hex ((cir_data >> 16) & 0x0f);
pin_input_buffer[7] = hex ((cir_data >> 12) & 0x0f);
pin_input_buffer[8] = hex ((cir_data >> 8) & 0x0f);
pin_input_buffer[9] = hex ((cir_data >> 4) & 0x0f);
pin_input_buffer[10] = hex (cir_data & 0x0f);
pin_input_buffer[11] = ':';
pin_input_buffer[12] = hex ((cir_data_more >> 12) & 0x0f);
pin_input_buffer[13] = hex ((cir_data_more >> 8) & 0x0f);
pin_input_buffer[14] = hex ((cir_data_more >> 4) & 0x0f);
pin_input_buffer[15] = hex (cir_data_more & 0x0f);
return CH_RETURN;
}
}
/*
* RC-5 protocol doesn't have a start bit, while any other protocols
* have the one.
@@ -207,125 +593,56 @@ static systime_t cir_input_last;
#define CIR_BIT_PERIOD 1500
#define CIR_BIT_SIRC_PERIOD_ON 1000
static void
cir_init (void)
{
cir_data = 0;
cir_seq = 0;
/* Don't touch cir_proto here */
cir_ext_enable ();
}
static Thread *pin_thread;
static int
cir_key_is_backspace (void)
/*
* Let user input PIN string.
* Return length of the string.
* The string itself is in PIN_INPUT_BUFFER.
*/
int
pinpad_getline (int msg_code, systime_t timeout)
{
return (cir_proto == CIR_PROTO_RC6 && cir_data == CIR_KEY_RC6_BACKSPACE)
|| (cir_proto == CIR_PROTO_NEC && cir_data == CIR_KEY_NEC_BACKSPACE)
|| (cir_proto == CIR_PROTO_SONY && cir_data == CIR_KEY_SONY_BACKSPACE)
|| (cir_proto == CIR_PROTO_SHARP && cir_data == CIR_KEY_SHARP_BACKSPACE);
}
static int
cir_key_is_enter (void)
{
return (cir_proto == CIR_PROTO_RC6 && cir_data == CIR_KEY_RC6_ENTER)
|| (cir_proto == CIR_PROTO_NEC && cir_data == CIR_KEY_NEC_ENTER)
|| (cir_proto == CIR_PROTO_SONY && cir_data == CIR_KEY_SONY_ENTER)
|| (cir_proto == CIR_PROTO_SHARP && cir_data == CIR_KEY_SHARP_ENTER);
}
msg_t
pin_main (void *arg)
{
uint8_t s = 0;
int msg_code = (int)arg;
(void)msg_code;
pin_thread = chThdSelf ();
#if defined(DEBUG_CIR)
cirinput_p = cirinput;
#endif
DEBUG_INFO (">>>\r\n");
pin_input_len = 0;
chEvtClear (ALL_EVENTS);
cir_init ();
while (!chThdShouldTerminate ())
while (1)
{
eventmask_t m;
int ch;
m = chEvtWaitOneTimeout (ALL_EVENTS, PINDISP_TIMEOUT_INTERVAL1);
ch = cir_getchar (timeout);
if (ch < 0)
return 0; /* timeout */
if (m)
if (ch_is_backspace (ch))
{
#if defined(DEBUG_CIR)
uint16_t *p;
DEBUG_INFO ("****\r\n");
DEBUG_SHORT (intr_ext);
DEBUG_SHORT (intr_trg);
DEBUG_SHORT (intr_ovf);
DEBUG_INFO ("----\r\n");
for (p = cirinput; p < cirinput_p; p++)
DEBUG_SHORT (*p);
DEBUG_INFO ("====\r\n");
cirinput_p = cirinput;
#endif
DEBUG_INFO ("**** CIR data:");
DEBUG_WORD (cir_data);
if (cir_seq > 48)
{
DEBUG_SHORT (cir_data_more);
}
DEBUG_BYTE (cir_seq);
if (cir_key_is_backspace ())
{
if (pin_input_len > 0)
pin_input_len--;
}
else if (cir_key_is_enter ())
{
pindisp (' ');
chThdExit (0);
}
else if (pin_input_len < MAX_PIN_CHARS)
pin_input_buffer[pin_input_len++] = (uint8_t)cir_data;
cir_init ();
led_blink (2);
if (pin_input_len > 0)
pin_input_len--;
}
switch (s++)
else if (ch_is_enter (ch))
break;
else if (pin_input_len < MAX_PIN_CHARS)
{
case 0:
pindisp ('G');
break;
case 1:
pindisp ('P');
break;
case 2:
pindisp ('G');
break;
case 3:
pindisp ('.');
break;
default:
pindisp (' ');
s = 0;
break;
led_blink (0);
pin_input_buffer[pin_input_len++] = ch;
}
chThdSleep (PINDISP_TIMEOUT_INTERVAL0);
}
cir_ext_disable ();
return 0;
return pin_input_len;
}
/**
* @brief Interrupt handler of EXTI.
* @note This handler will be invoked at the beginning of signal.
* Setup timer to measure period and duty using PWM input mode.
*/
void
cir_ext_interrupt (void)
{
@@ -340,29 +657,33 @@ cir_ext_interrupt (void)
}
#endif
TIM3->EGR = TIM_EGR_UG; /* Generate UEV to load PSC and ARR */
TIMx->EGR = TIM_EGR_UG; /* Generate UEV to load PSC and ARR */
/* Enable Timer */
TIM3->SR &= ~(TIM_SR_UIF
TIMx->SR &= ~(TIM_SR_UIF
| TIM_SR_CC1IF | TIM_SR_CC2IF
| TIM_SR_TIF
| TIM_SR_CC1OF | TIM_SR_CC2OF);
TIM3->DIER = TIM_DIER_UIE /*overflow*/ | TIM_DIER_TIE /*trigger*/;
TIM3->CR1 |= TIM_CR1_CEN;
TIMx->DIER = TIM_DIER_UIE /*overflow*/ | TIM_DIER_TIE /*trigger*/;
TIMx->CR1 |= TIM_CR1_CEN;
}
#define CIR_PERIOD_ON_RC5_OR_RC6 (((cir_proto == CIR_PROTO_RC5) ? 2 : 1) \
* CIR_BIT_PERIOD_RC6 * 3 / 2)
/**
* @brief Interrupt handler of timer.
* @note Timer is PWM input mode, this handler will be invoked on each cycle
*/
void
cir_timer_interrupt (void)
{
uint16_t period, on, off;
period = TIM3->CCR1;
on = TIM3->CCR2;
period = TIMx->CCR1;
on = TIMx->CCR2;
off = period - on;
if ((TIM3->SR & TIM_SR_TIF))
if ((TIMx->SR & TIM_SR_TIF))
{
if (cir_seq == 0)
{
@@ -477,23 +798,23 @@ cir_timer_interrupt (void)
intr_trg++;
#endif
TIM3->EGR = TIM_EGR_UG; /* Generate UEV */
TIM3->SR &= ~TIM_SR_TIF;
TIMx->EGR = TIM_EGR_UG; /* Generate UEV */
TIMx->SR &= ~TIM_SR_TIF;
}
else
/* overflow occurred */
{
systime_t now = chTimeNow ();
TIM3->SR &= ~TIM_SR_UIF;
TIMx->SR &= ~TIM_SR_UIF;
if (on > 0)
{
uint8_t ignore_input = 0;
/* Disable the timer */
TIM3->CR1 &= ~TIM_CR1_CEN;
TIM3->DIER = 0;
TIMx->CR1 &= ~TIM_CR1_CEN;
TIMx->DIER = 0;
if (cir_seq == 12 || cir_seq == 15)
{
@@ -536,14 +857,9 @@ cir_timer_interrupt (void)
cir_input_last = now;
ignore_input = 1;
}
/* Remove ADDRESS bits and filter COMMAND bits */
else if (cir_proto == CIR_PROTO_SONY)
{
if (cir_seq == 1 + 12)
cir_data = cir_data & 0x007f;
else if (cir_seq == 1 + 15)
cir_data = cir_data & 0x00ff;
else
if (cir_seq != 1 + 12 && cir_seq != 1 + 15)
ignore_input = 1;
}
else if (cir_proto == CIR_PROTO_OTHER)
@@ -551,10 +867,7 @@ cir_timer_interrupt (void)
if (cir_seq == 1 + 32)
{
if (((cir_data >> 16) & 0xff) == ((cir_data >> 24) ^ 0xff))
{
cir_proto = CIR_PROTO_NEC;
cir_data = (cir_data >> 16) & 0x00ff;
}
cir_proto = CIR_PROTO_NEC;
else
ignore_input = 1;
}
@@ -569,10 +882,7 @@ cir_timer_interrupt (void)
^ ((cir_data >> 20) & 0x0f) ^ ((cir_data >> 16) & 0x0f)
^ ((cir_data >> 12) & 0x0f) ^ ((cir_data >> 8) & 0x0f)
^ ((cir_data >> 4) & 0x0f) ^ (cir_data & 0x0f)))
{
cir_proto = CIR_PROTO_SHARP;
cir_data = (cir_data >> 16) & 0x0fff;
}
cir_proto = CIR_PROTO_SHARP;
else
ignore_input = 1;
}
@@ -581,16 +891,12 @@ cir_timer_interrupt (void)
}
else if (cir_proto == CIR_PROTO_RC6)
{
if (cir_seq == 16 || cir_seq == 32)
cir_data &= 0x00ff;
else
if (cir_seq != 16 && cir_seq != 32)
ignore_input = 1;
}
else if (cir_proto == CIR_PROTO_RC5)
{
if (cir_seq == 14)
cir_data &= 0x003f;
else
if (cir_seq != 14)
ignore_input = 1;
}
else
@@ -603,7 +909,8 @@ cir_timer_interrupt (void)
{
cir_input_last = now;
/* Notify thread */
chEvtSignal (pin_thread, (eventmask_t)1);
if (pin_thread)
chEvtSignalI (pin_thread, EV_PINPAD_INPUT_DONE);
}
#if defined(DEBUG_CIR)

View File

@@ -117,21 +117,19 @@ blink_dp (void)
}
static Thread *pin_thread;
#define EV_SW_PUSH (eventmask_t)1
void
dial_sw_interrupt (void)
{
dial_sw_disable ();
chEvtSignalI (pin_thread, EV_SW_PUSH);
chEvtSignalI (pin_thread, EV_PINPAD_INPUT_DONE);
palClearPad (IOPORT1, GPIOA_LED2);
}
msg_t
pin_main (void *arg)
int
pinpad_getline (int msg_code, systime_t timeout)
{
int msg_code = (int)arg;
uint16_t count, count_prev;
uint8_t input_mode;
uint8_t sw_push_count;
@@ -150,7 +148,7 @@ pin_main (void *arg)
sw_push_count = 0;
sw_event = 0;
while (!chThdShouldTerminate ())
while (1)
{
eventmask_t m;
@@ -158,7 +156,7 @@ pin_main (void *arg)
dial_sw_enable ();
m = chEvtWaitOneTimeout (ALL_EVENTS, LED_DISP_BLINK_INTERVAL0);
if (m == EV_SW_PUSH || sw_push_count)
if (m == EV_PINPAD_INPUT_DONE || sw_push_count)
{
if (palReadPad (IOPORT2, GPIOB_BUTTON) == 0)
sw_push_count++;
@@ -218,5 +216,5 @@ pin_main (void *arg)
led_disp (OFF);
TIM4->CR1 &= ~TIM_CR1_CEN;
dial_sw_disable ();
return 0;
return pin_input_len;
}

372
src/pin-dnd.c Normal file
View File

@@ -0,0 +1,372 @@
/*
* pin-dnd.c -- PIN input support (Drag and Drop with File Manager)
*
* Copyright (C) 2011 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
*
* Gnuk is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "ch.h"
#include "board.h"
#include "gnuk.h"
#include "usb-msc.h"
struct folder {
uint8_t parent;
uint8_t children[7];
};
static struct folder folders[8];
static const struct folder folder_ini = { 0, { 1, 2, 3, 4, 5, 6, 7 } };
uint8_t pin_input_buffer[MAX_PIN_CHARS];
uint8_t pin_input_len;
static Thread *pin_thread;
/*
* Let user input PIN string.
* Return length of the string.
* The string itself is in PIN_INPUT_BUFFER.
*/
int
pinpad_getline (int msg_code, systime_t timeout)
{
msg_t msg;
(void)msg_code;
(void)timeout;
DEBUG_INFO (">>>\r\n");
pin_input_len = 0;
msc_media_insert_change (1);
memset (folders, 0, sizeof folders);
memcpy (folders, &folder_ini, sizeof folder_ini);
while (1)
{
chSysLock ();
pin_thread = chThdSelf ();
chSchGoSleepS (THD_STATE_SUSPENDED);
msg = chThdSelf ()->p_u.rdymsg;
chSysUnlock ();
led_blink (0);
if (msg != 0)
break;
}
msc_media_insert_change (0);
if (msg == 1)
return pin_input_len;
else
return -1; /* cancel */
}
static void pinpad_input (void)
{
chSysLock ();
pin_thread->p_u.rdymsg = 0;
chSchReadyI (pin_thread);
chSysUnlock ();
}
static void pinpad_finish_entry (int cancel)
{
chSysLock ();
if (cancel)
pin_thread->p_u.rdymsg = 2;
else
pin_thread->p_u.rdymsg = 1;
chSchReadyI (pin_thread);
chSysUnlock ();
}
#define TOTAL_SECTOR 68
/*
blk=0: master boot record sector
blk=1: fat0
blk=2: fat1
blk=3: root directory
blk=4: fat cluster #2
...
blk=4+63: fat cluster #2+63
*/
static const uint8_t d0_0_sector[] = {
0xeb, 0x3c, /* Jump instruction */
0x90, /* NOP */
0x6d, 0x6b, 0x64, 0x6f, 0x73, 0x66, 0x73, 0x20, /* "mkdosfs " */
0x00, 0x02, /* Bytes per sector: 512 */
0x01, /* sectors per cluster: 1 */
0x01, 0x00, /* reserved sector count: 1 */
0x02, /* Number of FATs: 2 */
0x10, 0x00, /* Max. root directory entries: 16 (1 sector) */
TOTAL_SECTOR, 0x00, /* total sectors: 68 */
0xf8, /* media descriptor: fixed disk */
0x01, 0x00, /* sectors per FAT: 1 */
0x04, 0x00, /* sectors per track: 4 */
0x01, 0x00, /* number of heads: 1 */
0x00, 0x00, 0x00, 0x00, /* hidden sectors: 0 */
0x00, 0x00, 0x00, 0x00, /* total sectors (long) */
0x00, /* drive number */
0x00, /* reserved */
0x29, /* extended boot signature */
0xbf, 0x86, 0x75, 0xea, /* Volume ID (serial number) (Little endian) */
/* Volume label: DNDpinentry */
'D', 'n', 'D', 'p', 'i', 'n', 'e', 'n', 't', 'r', 'y',
0x46, 0x41, 0x54, 0x31, 0x32, 0x20, 0x20, 0x20, /* FAT12 */
0x0e, /* push cs */
0x1f, /* pop ds */
0xbe, 0x5b, 0x7c, /* mov si, offset message_txt */
0xac, /* 1: lodsb */
0x22, 0xc0, /* and al, al */
0x74, 0x0b, /* jz 2f */
0x56, /* push si */
0xb4, 0x0e, /* mov ah, 0eh */
0xbb, 0x07, 0x00, /* mov bx, 0007h */
0xcd, 0x10, /* int 10h ; output char color=white */
0x5e, /* pop si */
0xeb, 0xf0, /* jmp 1b */
0x32, 0xe4, /* 2: xor ah, ah */
0xcd, 0x16, /* int 16h; key input */
0xcd, 0x19, /* int 19h; load OS */
0xeb, 0xfe, /* 3: jmp 3b */
/* "This is not a bootable disk... \r\n" */
0x54, 0x68, 0x69, 0x73, 0x20,
0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x61,
0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
0x65, 0x20, 0x64, 0x69, 0x73, 0x6b, 0x2e, 0x20,
0x20, 0x50, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x20,
0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x61,
0x20, 0x62, 0x6f, 0x6f, 0x74, 0x61, 0x62, 0x6c,
0x65, 0x20, 0x66, 0x6c, 0x6f, 0x70, 0x70, 0x79,
0x20, 0x61, 0x6e, 0x64, 0x0d, 0x0a, 0x70, 0x72,
0x65, 0x73, 0x73, 0x20, 0x61, 0x6e, 0x79, 0x20,
0x6b, 0x65, 0x79, 0x20, 0x74, 0x6f, 0x20, 0x74,
0x72, 0x79, 0x20, 0x61, 0x67, 0x61, 0x69, 0x6e,
0x20, 0x2e, 0x2e, 0x2e, 0x20, 0x0d, 0x0a, 0x00,
};
static const uint8_t d0_fat0_sector[] = {
0xf8, 0xff, 0xff, /* Media descriptor: fixed disk */ /* EOC */
0xff, 0xff, 0xff, /* cluster 2: used */ /* cluster 3: used */
0xff, 0xff, 0xff, /* cluster 4: used */ /* cluster 5: used */
0xff, 0xff, 0xff, /* cluster 6: used */ /* cluster 7: used */
0xff, 0x0f, 0x00, /* cluster 8: used */ /* cluster 9: free */
};
static uint8_t the_sector[512];
#define FOLDER_INDEX_TO_CLUSTER_NO(i) (i+1)
#define CLUSTER_NO_TO_FOLDER_INDEX(n) (n-1)
#define FOLDER_INDEX_TO_LBA(i) (i+3)
#define LBA_TO_FOLDER_INDEX(lba) (lba-3)
#define FOLDER_INDEX_TO_DIRCHAR(i) ('A'+i-1)
#define DIRCHAR_TO_FOLDER_INDEX(c) (c - 'A' + 1)
static uint8_t *fill_file_entry (uint8_t *p, const uint8_t *filename,
uint16_t cluster_no)
{
memcpy (p, filename, 8+3);
p += 11;
*p++ = 0x10; /* directory */
*p++ = 0x00; /* reserved */
memcpy (p, "\x64\x3b\xa7\x61\x3f", 5); /* create time */
p += 5;
memcpy (p, "\x61\x3f", 2); /* last access */
p += 2;
*p++ = 0x00; *p++ = 0x00; /* ea-index */
memcpy (p, "\x3b\xa7\x61\x3f", 4); /* last modified */
p += 4;
memcpy (p, &cluster_no, 2); /* cluster # */
p += 2;
*p++ = 0x00; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00; /* file size */
return p;
}
static void build_directory_sector (uint8_t *p, uint8_t index)
{
uint16_t cluster_no = FOLDER_INDEX_TO_CLUSTER_NO (index);
int i;
uint8_t filename[11] = { 0x2e, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20 };
uint8_t child;
memset (p, 0, 512);
if (index != 0)
{
p = fill_file_entry (p, filename, cluster_no);
filename[1] = 0x2e;
p = fill_file_entry (p, filename, 0);
filename[1] = 0x20;
}
for (i = 0; i < 7; i++)
if ((child = folders[index].children[i]) != 0)
{
filename[0] = FOLDER_INDEX_TO_DIRCHAR (child);
p = fill_file_entry (p, filename, FOLDER_INDEX_TO_CLUSTER_NO (child));
}
else
break;
}
int
msc_scsi_read (uint32_t lba, const uint8_t **sector_p)
{
if (!media_available)
return SCSI_ERROR_NOT_READY;
if (lba >= TOTAL_SECTOR)
return SCSI_ERROR_ILLEAGAL_REQUEST;
switch (lba)
{
case 0:
*sector_p = the_sector;
memcpy (the_sector, d0_0_sector, sizeof d0_0_sector);
memset (the_sector + sizeof d0_0_sector, 0, 512 - sizeof d0_0_sector);
the_sector[510] = 0x55;
the_sector[511] = 0xaa;
return 0;
case 1:
case 2:
*sector_p = the_sector;
memcpy (the_sector, d0_fat0_sector, sizeof d0_fat0_sector);
memset (the_sector + sizeof d0_fat0_sector, 0,
512 - sizeof d0_fat0_sector);
return 0;
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
*sector_p = the_sector;
build_directory_sector (the_sector, LBA_TO_FOLDER_INDEX (lba));
return 0;
default:
*sector_p = the_sector;
memset (the_sector, 0, 512);
return 0;
}
}
static void parse_directory_sector (const uint8_t *p, uint8_t index)
{
int i;
uint8_t child;
int input = 0;
int num_children = 0;
if (index != 0)
{
uint16_t cluster_no;
uint8_t dest_index;
p += 32; /* skip "." */
/* ".." */
cluster_no = p[26] | (p[27] << 8);
dest_index = CLUSTER_NO_TO_FOLDER_INDEX (cluster_no);
if (dest_index < 1 || dest_index > 7)
; /* it can be 255 : root_dir */
else
if (pin_input_len < MAX_PIN_CHARS - 2)
{
pin_input_buffer[pin_input_len++]
= FOLDER_INDEX_TO_DIRCHAR (index);
pin_input_buffer[pin_input_len++]
= FOLDER_INDEX_TO_DIRCHAR (dest_index);
input = 1;
}
p += 32;
}
for (i = 0; i < 7; i++)
{
if (*p >= 'A' && *p <= 'G')
{
child = DIRCHAR_TO_FOLDER_INDEX (*p);
folders[index].children[i] = child;
num_children++;
}
else
folders[index].children[i] = 0;
p += 32;
}
if (index == 0 && num_children == 1)
pinpad_finish_entry (0);
else if (input)
pinpad_input ();
}
int
msc_scsi_write (uint32_t lba, const uint8_t *buf, size_t size)
{
(void)size;
if (!media_available)
return SCSI_ERROR_NOT_READY;
if (lba >= TOTAL_SECTOR)
return SCSI_ERROR_ILLEAGAL_REQUEST;
if (lba == 1)
return 0; /* updating FAT, just ignore */
if (lba <= 2 || lba >= 11)
return SCSI_ERROR_DATA_PROTECT;
else
{
uint8_t index = LBA_TO_FOLDER_INDEX (lba);
parse_directory_sector (buf, index);
return 0;
}
}
void
msc_scsi_stop (uint8_t code)
{
(void)code;
pinpad_finish_entry (1);
}

View File

@@ -24,6 +24,23 @@
#include "config.h"
#include "ch.h"
#include "gnuk.h"
#include "neug.h"
#define RANDOM_BYTES_LENGTH 16
static uint32_t random_word[RANDOM_BYTES_LENGTH/sizeof (uint32_t)];
void
random_init (void)
{
int i;
neug_init (random_word, RANDOM_BYTES_LENGTH/sizeof (uint32_t));
for (i = 0; i < NEUG_PRE_LOOP; i++)
(void)neug_get (NEUG_KICK_FILLING);
neug_prng_reseed ();
}
/*
* Return pointer to random 16-byte
@@ -31,25 +48,8 @@
const uint8_t *
random_bytes_get (void)
{
uint32_t addr, addr0;
addr = (uint32_t)&random_bits_start + ((hardclock () << 4) & 0x3f0);
addr0 = addr;
while (1)
{
if (*(uint32_t *)addr != 0 && *(uint32_t *)addr != 0xffffffff)
break;
addr += 16;
if (addr >= ((uint32_t)&random_bits_start) + 1024)
addr = ((uint32_t)&random_bits_start);
if (addr == addr0)
fatal (FATAL_RANDOM);
}
return (const uint8_t *)addr;
neug_wait_full ();
return (const uint8_t *)random_word;
}
/*
@@ -58,11 +58,8 @@ random_bytes_get (void)
void
random_bytes_free (const uint8_t *p)
{
int i;
uint32_t addr = (uint32_t)p;
for (i = 0; i < 8; i++)
flash_clear_halfword (addr+i*2);
(void)p;
neug_flush ();
}
/*
@@ -71,15 +68,5 @@ random_bytes_free (const uint8_t *p)
uint32_t
get_salt (void)
{
const uint8_t *u = unique_device_id (); /* 12-byte unique id */
uint32_t r = 0;
int i;
for (i = 0; i < 4; i++)
{
r <<= 8;
r |= u[hardclock () % 12];
}
return r;
return neug_get (NEUG_KICK_FILLING);
}

View File

@@ -1,7 +0,0 @@
STMUSBDIR = ../STM32_USB-FS-Device_Driver
STMUSBSRCDIR = $(STMUSBDIR)/src
STMUSBINCDIR = $(STMUSBDIR)/inc
STMUSBSRC= $(STMUSBSRCDIR)/usb_sil.c \
$(STMUSBSRCDIR)/usb_init.c $(STMUSBSRCDIR)/usb_int.c \
$(STMUSBSRCDIR)/usb_mem.c $(STMUSBSRCDIR)/usb_core.c \
$(STMUSBSRCDIR)/usb_regs.c

View File

@@ -1,93 +0,0 @@
/*
* This file is included by usb_prop.c to provide Virtual COM port feature
*/
/* Original is ../Virtual_COM_Port/usb_prop.c by STMicroelectronics */
/* Chopped and modified for Gnuk */
#include "usb-cdc.h"
/* Original copyright notice is following: */
/******************** (C) COPYRIGHT 2010 STMicroelectronics ********************
* File Name : usb_prop.c
* Author : MCD Application Team
* Version : V3.1.1
* Date : 04/07/2010
* Description : All processing related to Virtual Com Port Demo
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
typedef struct
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
} LINE_CODING;
static LINE_CODING linecoding = {
115200, /* baud rate*/
0x00, /* stop bits-1*/
0x00, /* parity - none*/
0x08 /* no. of bits 8*/
};
static uint8_t *Virtual_Com_Port_GetLineCoding(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
return NULL;
}
return (uint8_t *)&linecoding;
}
static uint8_t *Virtual_Com_Port_SetLineCoding(uint16_t Length)
{
if (Length == 0)
{
pInformation->Ctrl_Info.Usb_wLength = sizeof(linecoding);
return NULL;
}
return (uint8_t *)&linecoding;
}
static RESULT
Virtual_Com_Port_Data_Setup (uint8_t RequestNo)
{
uint8_t *(*CopyRoutine)(uint16_t);
CopyRoutine = NULL;
if (RequestNo == USB_CDC_REQ_GET_LINE_CODING)
CopyRoutine = Virtual_Com_Port_GetLineCoding;
else if (RequestNo == USB_CDC_REQ_SET_LINE_CODING)
CopyRoutine = Virtual_Com_Port_SetLineCoding;
if (CopyRoutine == NULL)
return USB_UNSUPPORT;
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine) (0); /* Set Ctrl_Info.Usb_wLength */
return USB_SUCCESS;
}
static RESULT
Virtual_Com_Port_NoData_Setup (uint8_t RequestNo)
{
if (RequestNo == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
/* Do nothing and success */
return USB_SUCCESS;
return USB_UNSUPPORT;
}

View File

@@ -5,3 +5,6 @@
#define USB_CDC_REQ_GET_LINE_CODING 0x21
#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22
#define USB_CDC_REQ_SEND_BREAK 0x23
#define VIRTUAL_COM_PORT_DATA_SIZE 16
#define VIRTUAL_COM_PORT_INT_SIZE 8

File diff suppressed because it is too large Load Diff

550
src/usb-msc.c Normal file
View File

@@ -0,0 +1,550 @@
/*
* usb-msc.c -- USB Mass Storage Class protocol handling
*
* Copyright (C) 2011, 2012 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
*
* Gnuk is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Gnuk is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
* License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "config.h"
#include "ch.h"
#include "gnuk.h"
#include "usb_lld.h"
#include "usb-msc.h"
struct usb_endp_in {
const uint8_t *txbuf; /* Pointer to the transmission buffer. */
size_t txsize; /* Transmit transfer size remained. */
size_t txcnt; /* Transmitted bytes so far. */
};
struct usb_endp_out {
uint8_t *rxbuf; /* Pointer to the receive buffer. */
size_t rxsize; /* Requested receive transfer size. */
size_t rxcnt; /* Received bytes so far. */
};
static struct usb_endp_in ep6_in;
static struct usb_endp_out ep6_out;
static Thread *the_thread;
#define ENDP_MAX_SIZE 64
static uint8_t msc_state;
static void usb_start_transmit (const uint8_t *p, size_t n)
{
size_t pkt_len = n > ENDP_MAX_SIZE ? ENDP_MAX_SIZE : n;
ep6_in.txbuf = p;
ep6_in.txsize = n;
ep6_in.txcnt = 0;
usb_lld_write (ENDP6, (uint8_t *)ep6_in.txbuf, pkt_len);
}
/* "Data Transmitted" callback */
void EP6_IN_Callback (void)
{
size_t n = (size_t)usb_lld_tx_data_len (ENDP6);
ep6_in.txbuf += n;
ep6_in.txcnt += n;
ep6_in.txsize -= n;
if (ep6_in.txsize > 0) /* More data to be sent */
{
if (ep6_in.txsize > ENDP_MAX_SIZE)
n = ENDP_MAX_SIZE;
else
n = ep6_in.txsize;
usb_lld_write (ENDP6, (uint8_t *)ep6_in.txbuf, n);
return;
}
/* Transmit has been completed, notify the waiting thread */
switch (msc_state)
{
case MSC_SENDING_CSW:
case MSC_DATA_IN:
if (the_thread != NULL) {
Thread *tp;
chSysLockFromIsr ();
tp = the_thread;
the_thread = NULL;
tp->p_u.rdymsg = RDY_OK;
chSchReadyI (tp);
chSysUnlockFromIsr ();
}
break;
default:
break;
}
}
static void usb_start_receive (uint8_t *p, size_t n)
{
ep6_out.rxbuf = p;
ep6_out.rxsize = n;
ep6_out.rxcnt = 0;
usb_lld_rx_enable (ENDP6);
}
/* "Data Received" call back */
void EP6_OUT_Callback (void)
{
size_t n = (size_t)usb_lld_rx_data_len (ENDP6);
int err = 0;
if (n > ep6_out.rxsize)
{ /* buffer overflow */
err = 1;
n = ep6_out.rxsize;
}
usb_lld_rxcpy (ep6_out.rxbuf, ENDP6, 0, n);
ep6_out.rxbuf += n;
ep6_out.rxcnt += n;
ep6_out.rxsize -= n;
if (n == ENDP_MAX_SIZE && ep6_out.rxsize != 0)
{ /* More data to be received */
usb_lld_rx_enable (ENDP6);
return;
}
/* Receiving has been completed, notify the waiting thread */
switch (msc_state)
{
case MSC_IDLE:
case MSC_DATA_OUT:
if (the_thread != NULL) {
Thread *tp;
chSysLockFromIsr ();
tp = the_thread;
the_thread = NULL;
tp->p_u.rdymsg = err? RDY_RESET : RDY_OK;
chSchReadyI (tp);
chSysUnlockFromIsr ();
}
break;
default:
break;
}
}
static const uint8_t scsi_inquiry_data_00[] = { 0, 0, 0, 0, 0 };
static const uint8_t scsi_inquiry_data[] = {
0x00, /* Direct Access Device. */
0x80, /* RMB = 1: Removable Medium. */
0x05, /* Version: SPC-3. */
0x02, /* Response format: SPC-3. */
36 - 4, /* Additional Length. */
0x00,
0x00,
0x00,
/* Vendor Identification */
'F', 'S', 'I', 'J', ' ', ' ', ' ', ' ',
/* Product Identification */
'V', 'i', 'r', 't', 'u', 'a', 'l', ' ',
'D', 'i', 's', 'k', ' ', ' ', ' ', ' ',
/* Product Revision Level */
'1', '.', '0', ' '
};
static uint8_t scsi_sense_data_desc[] = {
0x72, /* Response Code: descriptor, current */
0x02, /* Sense Key */
0x3a, /* ASC (additional sense code) */
0x00, /* ASCQ (additional sense code qualifier) */
0x00, 0x00, 0x00,
0x00, /* Additional Sense Length */
};
static uint8_t scsi_sense_data_fixed[] = {
0x70, /* Response Code: fixed, current */
0x00,
0x02, /* Sense Key */
0x00, 0x00, 0x00, 0x00,
0x0a, /* Additional Sense Length */
0x00, 0x00, 0x00, 0x00,
0x3a, /* ASC (additional sense code) */
0x00, /* ASCQ (additional sense code qualifier) */
0x00,
0x00, 0x00, 0x00,
};
static void set_scsi_sense_data(uint8_t sense_key, uint8_t asc) {
scsi_sense_data_desc[1] = scsi_sense_data_fixed[2] = sense_key;
scsi_sense_data_desc[2] = scsi_sense_data_fixed[12] = asc;
}
static uint8_t buf[512];
static uint8_t contingent_allegiance;
static uint8_t keep_contingent_allegiance;
uint8_t media_available;
void msc_media_insert_change (int available)
{
contingent_allegiance = 1;
media_available = available;
if (available)
{
set_scsi_sense_data (0x06, 0x28); /* UNIT_ATTENTION */
keep_contingent_allegiance = 0;
}
else
{
set_scsi_sense_data (0x02, 0x3a); /* NOT_READY */
keep_contingent_allegiance = 1;
}
}
static uint8_t scsi_read_format_capacities (uint32_t *nblocks,
uint32_t *secsize)
{
*nblocks = 68;
*secsize = 512;
if (media_available)
return 2; /* Formatted Media.*/
else
return 3; /* No Media.*/
}
static struct CBW CBW;
static struct CSW CSW;
static int msc_recv_data (void)
{
msg_t msg;
chSysLock ();
msc_state = MSC_DATA_OUT;
the_thread = chThdSelf ();
usb_start_receive (buf, 512);
chSchGoSleepS (THD_STATE_SUSPENDED);
msg = chThdSelf ()->p_u.rdymsg;
chSysUnlock ();
return 0;
}
static void msc_send_data (const uint8_t *p, size_t n)
{
msg_t msg;
chSysLock ();
msc_state = MSC_DATA_IN;
the_thread = chThdSelf ();
usb_start_transmit (p, n);
chSchGoSleepS (THD_STATE_SUSPENDED);
msg = chThdSelf ()->p_u.rdymsg;
CSW.dCSWDataResidue -= (uint32_t)n;
chSysUnlock();
}
static void msc_send_result (const uint8_t *p, size_t n)
{
msg_t msg;
if (p != NULL)
{
if (n > CBW.dCBWDataTransferLength)
n = CBW.dCBWDataTransferLength;
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength;
msc_send_data (p, n);
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
}
CSW.dCSWSignature = MSC_CSW_SIGNATURE;
chSysLock ();
msc_state = MSC_SENDING_CSW;
the_thread = chThdSelf ();
usb_start_transmit ((uint8_t *)&CSW, sizeof CSW);
chSchGoSleepS (THD_STATE_SUSPENDED);
msg = chThdSelf ()->p_u.rdymsg;
chSysUnlock ();
}
void msc_handle_command (void)
{
size_t n;
uint32_t nblocks, secsize;
uint32_t lba;
int r;
msg_t msg;
chSysLock();
msc_state = MSC_IDLE;
the_thread = chThdSelf ();
usb_start_receive ((uint8_t *)&CBW, sizeof CBW);
chSchGoSleepTimeoutS (THD_STATE_SUSPENDED, MS2ST (1000));
msg = chThdSelf ()->p_u.rdymsg;
chSysUnlock ();
if (msg != RDY_OK)
{
/* Error occured, ignore the request and go into error state */
msc_state = MSC_ERROR;
if (msg != RDY_TIMEOUT)
{
chSysLock ();
usb_lld_stall_rx (ENDP6);
chSysUnlock ();
}
return;
}
n = ep6_out.rxcnt;
if ((n != sizeof (struct CBW)) || (CBW.dCBWSignature != MSC_CBW_SIGNATURE))
{
msc_state = MSC_ERROR;
chSysLock ();
usb_lld_stall_rx (ENDP6);
chSysUnlock ();
return;
}
CSW.dCSWTag = CBW.dCBWTag;
switch (CBW.CBWCB[0]) {
case SCSI_REQUEST_SENSE:
if (CBW.CBWCB[1] & 0x01) /* DESC */
msc_send_result ((uint8_t *)&scsi_sense_data_desc,
sizeof scsi_sense_data_desc);
else
msc_send_result ((uint8_t *)&scsi_sense_data_fixed,
sizeof scsi_sense_data_fixed);
/* After the error is reported, clear it, if it's . */
if (!keep_contingent_allegiance)
{
contingent_allegiance = 0;
set_scsi_sense_data (0x00, 0x00);
}
return;
case SCSI_INQUIRY:
if (CBW.CBWCB[1] & 0x01) /* EVPD */
/* assume page 00 */
msc_send_result ((uint8_t *)&scsi_inquiry_data_00,
sizeof scsi_inquiry_data_00);
else
msc_send_result ((uint8_t *)&scsi_inquiry_data,
sizeof scsi_inquiry_data);
return;
case SCSI_READ_FORMAT_CAPACITIES:
buf[8] = scsi_read_format_capacities (&nblocks, &secsize);
buf[0] = buf[1] = buf[2] = 0;
buf[3] = 8;
buf[4] = (uint8_t)(nblocks >> 24);
buf[5] = (uint8_t)(nblocks >> 16);
buf[6] = (uint8_t)(nblocks >> 8);
buf[7] = (uint8_t)(nblocks >> 0);
buf[9] = (uint8_t)(secsize >> 16);
buf[10] = (uint8_t)(secsize >> 8);
buf[11] = (uint8_t)(secsize >> 0);
msc_send_result (buf, 12);
return;
case SCSI_START_STOP_UNIT:
if (CBW.CBWCB[4] == 0x00 /* stop */
|| CBW.CBWCB[4] == 0x02 /* eject */ || CBW.CBWCB[4] == 0x03 /* close */)
{
msc_scsi_stop (CBW.CBWCB[4]);
set_scsi_sense_data (0x05, 0x24); /* ILLEGAL_REQUEST */
contingent_allegiance = 1;
keep_contingent_allegiance = 1;
}
/* CBW.CBWCB[4] == 0x01 *//* start */
goto success;
case SCSI_TEST_UNIT_READY:
if (contingent_allegiance)
{
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
CSW.dCSWDataResidue = 0;
msc_send_result (NULL, 0);
return;
}
/* fall through */
success:
case SCSI_SYNCHRONIZE_CACHE:
case SCSI_VERIFY10:
case SCSI_ALLOW_MEDIUM_REMOVAL:
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength;
msc_send_result (NULL, 0);
return;
case SCSI_MODE_SENSE6:
buf[0] = 0x03;
buf[1] = buf[2] = buf[3] = 0;
msc_send_result (buf, 4);
return;
case SCSI_READ_CAPACITY10:
scsi_read_format_capacities (&nblocks, &secsize);
buf[0] = (uint8_t)((nblocks - 1) >> 24);
buf[1] = (uint8_t)((nblocks - 1) >> 16);
buf[2] = (uint8_t)((nblocks - 1) >> 8);
buf[3] = (uint8_t)((nblocks - 1) >> 0);
buf[4] = (uint8_t)(secsize >> 24);
buf[5] = (uint8_t)(secsize >> 16);
buf[6] = (uint8_t)(secsize >> 8);
buf[7] = (uint8_t)(secsize >> 0);
msc_send_result (buf, 8);
return;
case SCSI_READ10:
case SCSI_WRITE10:
break;
default:
if (CBW.dCBWDataTransferLength == 0)
{
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
CSW.dCSWDataResidue = 0;
msc_send_result (NULL, 0);
return;
}
else
{
msc_state = MSC_ERROR;
chSysLock ();
usb_lld_stall_tx (ENDP6);
usb_lld_stall_rx (ENDP6);
chSysUnlock ();
return;
}
}
lba = (CBW.CBWCB[2] << 24) | (CBW.CBWCB[3] << 16)
| (CBW.CBWCB[4] << 8) | CBW.CBWCB[5];
/* Transfer direction.*/
if (CBW.bmCBWFlags & 0x80)
{
/* IN, Device to Host.*/
msc_state = MSC_DATA_IN;
if (CBW.CBWCB[0] == SCSI_READ10)
{
const uint8_t *p;
CSW.dCSWDataResidue = 0;
while (1)
{
if (CBW.CBWCB[7] == 0 && CBW.CBWCB[8] == 0)
{
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
break;
}
if ((r = msc_scsi_read (lba, &p)) == 0)
{
msc_send_data (p, 512);
if (++CBW.CBWCB[5] == 0)
if (++CBW.CBWCB[4] == 0)
if (++CBW.CBWCB[3] == 0)
++CBW.CBWCB[2];
if (CBW.CBWCB[8]-- == 0)
CBW.CBWCB[7]--;
CSW.dCSWDataResidue += 512;
}
else
{
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
contingent_allegiance = 1;
if (r == SCSI_ERROR_NOT_READY)
set_scsi_sense_data (SCSI_ERROR_NOT_READY, 0x3a);
else
set_scsi_sense_data (r, 0x00);
break;
}
}
msc_send_result (NULL, 0);
}
}
else
{
/* OUT, Host to Device.*/
if (CBW.CBWCB[0] == SCSI_WRITE10)
{
CSW.dCSWDataResidue = CBW.dCBWDataTransferLength;
while (1)
{
if (CBW.CBWCB[8] == 0 && CBW.CBWCB[7] == 0)
{
CSW.bCSWStatus = MSC_CSW_STATUS_PASSED;
break;
}
msc_recv_data ();
if ((r = msc_scsi_write (lba, buf, 512)) == 0)
{
if (++CBW.CBWCB[5] == 0)
if (++CBW.CBWCB[4] == 0)
if (++CBW.CBWCB[3] == 0)
++CBW.CBWCB[2];
if (CBW.CBWCB[8]-- == 0)
CBW.CBWCB[7]--;
CSW.dCSWDataResidue -= 512;
}
else
{
CSW.bCSWStatus = MSC_CSW_STATUS_FAILED;
contingent_allegiance = 1;
if (r == SCSI_ERROR_NOT_READY)
set_scsi_sense_data (SCSI_ERROR_NOT_READY, 0x3a);
else
set_scsi_sense_data (r, 0x00);
break;
}
}
msc_send_result (NULL, 0);
}
}
}
static msg_t
msc_main (void *arg)
{
(void)arg;
/* Initially, it starts with no media */
msc_media_insert_change (0);
while (1)
msc_handle_command ();
return 0;
}
static WORKING_AREA(wa_msc_thread, 128);
void msc_init (void)
{
chThdCreateStatic (wa_msc_thread, sizeof (wa_msc_thread),
NORMALPRIO, msc_main, NULL);
}

52
src/usb-msc.h Normal file
View File

@@ -0,0 +1,52 @@
#define MSC_CBW_SIGNATURE 0x43425355
#define MSC_CSW_SIGNATURE 0x53425355
#define MSC_GET_MAX_LUN_COMMAND 0xFE
#define MSC_MASS_STORAGE_RESET_COMMAND 0xFF
#define MSC_CSW_STATUS_PASSED 0
#define MSC_CSW_STATUS_FAILED 1
#define SCSI_INQUIRY 0x12
#define SCSI_MODE_SENSE6 0x1A
#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E
#define SCSI_READ10 0x28
#define SCSI_READ_CAPACITY10 0x25
#define SCSI_REQUEST_SENSE 0x03
#define SCSI_START_STOP_UNIT 0x1B
#define SCSI_TEST_UNIT_READY 0x00
#define SCSI_WRITE10 0x2A
#define SCSI_VERIFY10 0x2F
#define SCSI_READ_FORMAT_CAPACITIES 0x23
#define SCSI_SYNCHRONIZE_CACHE 0x35
#define MSC_IDLE 0
#define MSC_DATA_OUT 1
#define MSC_DATA_IN 2
#define MSC_SENDING_CSW 3
#define MSC_ERROR 4
struct CBW {
uint32_t dCBWSignature;
uint32_t dCBWTag;
uint32_t dCBWDataTransferLength;
uint8_t bmCBWFlags;
uint8_t bCBWLUN;
uint8_t bCBWCBLength;
uint8_t CBWCB[16];
} __attribute__((packed));
struct CSW {
uint32_t dCSWSignature;
uint32_t dCSWTag;
uint32_t dCSWDataResidue;
uint8_t bCSWStatus;
} __attribute__((packed));
#define SCSI_ERROR_NOT_READY 2
#define SCSI_ERROR_ILLEAGAL_REQUEST 5
#define SCSI_ERROR_UNIT_ATTENTION 6
#define SCSI_ERROR_DATA_PROTECT 7
extern uint8_t media_available;

View File

@@ -1,37 +1,40 @@
/* USB configuration file for USB-FS-Device_Lib */
/*
* For detail, please see the documentation of
* STM32F10x USB Full Speed Device Library (USB-FS-Device_Lib)
* by STMicroelectronics
*/
/* USB buffer memory definition and number of string descriptors */
#ifndef __USB_CONF_H
#define __USB_CONF_H
#ifdef ENABLE_VIRTUAL_COM_PORT
#define EP_NUM (6)
#else
#define EP_NUM (3)
#endif
#define BTABLE_ADDRESS (0x00)
#define NUM_STRING_DESC 4
/* Control pipe */
/* EP0 */
#define ENDP0_RXADDR (0x40)
#define ENDP0_TXADDR (0x80)
/* CCID/ICCD BULK_IN, BULK_OUT */
/* EP1 */
#define ENDP1_TXADDR (0xc0)
#define ENDP1_RXADDR (0x100)
/* HID INTR_IN, INTR_OUT */
/* EP2 */
#define ENDP2_RXADDR (0x100)
#define ENDP2_TXADDR (0x140)
#define ENDP2_RXADDR (0x148)
/* CDC BULK_IN, INTR_IN, BULK_OUT */
/* EP3 */
#define ENDP3_TXADDR (0x140)
#define ENDP3_TXADDR (0x14a)
/* EP4 */
#define ENDP4_TXADDR (0x180)
#define ENDP4_TXADDR (0x15a)
/* EP5 */
#define ENDP5_RXADDR (0x190)
#define ENDP5_RXADDR (0x162)
#define IMR_MSK (CNTR_CTRM | CNTR_SOFM | CNTR_RESETM )
/* 0x172 - 0x180 : 14-byte */
/* MSC BULK_IN, BULK_OUT */
/* EP6 */
#define ENDP6_TXADDR (0x180)
#define ENDP6_RXADDR (0x1c0)
/* EP7: free */
#endif /* __USB_CONF_H */

View File

@@ -3,8 +3,10 @@
*/
#include "config.h"
#include "usb_lib.h"
#include "usb_desc.h"
#include "ch.h"
#include "usb_lld.h"
#include "usb_conf.h"
#include "usb-cdc.h"
#define USB_ICC_INTERFACE_CLASS 0x0B
#define USB_ICC_INTERFACE_SUBCLASS 0x00
@@ -15,28 +17,41 @@
static const uint8_t gnukDeviceDescriptor[] = {
18, /* bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
0x00, 0x02, /* bcdUSB = 2.00 */
0x10, 0x01, /* bcdUSB = 1.1 */
0x00, /* bDeviceClass: 0 means deferred to interface */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize0 */
0x4b, 0x23, /* idVendor = 0x234b (FSIJ) */
0x00, 0x00, /* idProduct = 0x0000 (FSIJ USB Token) */
0x00, 0x02, /* bcdDevice = 2.00 */
#include "usb-vid-pid-ver.c.inc"
1, /* Index of string descriptor describing manufacturer */
2, /* Index of string descriptor describing product */
3, /* Index of string descriptor describing the device's serial number */
0x01 /* bNumConfigurations */
};
#define ICC_TOTAL_LENGTH (9+9+54+7+7)
#define ICC_NUM_INTERFACES 1
#ifdef ENABLE_VIRTUAL_COM_PORT
#define W_TOTAL_LENGTH (9+9+54+7+7+9+5+5+4+5+7+9+7+7)
#define NUM_INTERFACES 3 /* two for CDC, one for GPG */
#define VCOM_TOTAL_LENGTH (9+5+5+4+5+7+9+7+7)
#define VCOM_NUM_INTERFACES 2
#else
#define W_TOTAL_LENGTH (9+9+54+7+7)
#define NUM_INTERFACES 1 /* GPG only */
#define VCOM_TOTAL_LENGTH 0
#define VCOM_NUM_INTERFACES 0
#endif
#ifdef PINPAD_DND_SUPPORT
#define MSC_TOTAL_LENGTH (9+7+7)
#define MSC_NUM_INTERFACES 1
#else
#define MSC_TOTAL_LENGTH 0
#define MSC_NUM_INTERFACES 0
#endif
#define W_TOTAL_LENGTH (ICC_TOTAL_LENGTH+VCOM_TOTAL_LENGTH+MSC_TOTAL_LENGTH)
#define NUM_INTERFACES (ICC_NUM_INTERFACES+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES)
/* Configuation Descriptor */
static const uint8_t gnukConfigDescriptor[] = {
9, /* bLength: Configuation Descriptor size */
@@ -86,8 +101,8 @@ static const uint8_t gnukConfigDescriptor[] = {
* It is different now for better interaction to GPG's in-stock
* ccid-driver.
*/
0x42, 0x08, 0x04, 0x00, /* dwFeatures (not ICCD):
* Short and extended APDU level: 0x40000 *
0x42, 0x08, 0x02, 0x00, /* dwFeatures (not ICCD):
* Short APDU level : 0x20000 *
* (what? means ICCD?) : 0x00800 *
* Automatic IFSD : 0x00400
* NAD value other than 0x00 : 0x00200
@@ -100,12 +115,12 @@ static const uint8_t gnukConfigDescriptor[] = {
* Auto activaction of ICC : 0x00004
* Automatic conf. based on ATR : 0x00002 g
*/
0x40, 0x01, 0, 0, /* dwMaxCCIDMessageLength */
0x0f, 0x01, 0, 0, /* dwMaxCCIDMessageLength: 271 */
0xff, /* bClassGetResponse: */
0xff, /* bClassEnvelope: */
0, 0, /* wLCDLayout: FIXED VALUE */
#if defined(PINPAD_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT)
#if defined(PINPAD_CIR_SUPPORT) || defined(PINPAD_DND_SUPPORT)
1, /* bPinSupport: with PIN pad (verify) */
#elif defined(PINPAD_DIAL_SUPPORT)
3, /* bPinSupport: with PIN pad (verify, modify) */
@@ -114,17 +129,17 @@ static const uint8_t gnukConfigDescriptor[] = {
0, /* bPinSupport: No PIN pad */
#endif
1, /* bMaxCCIDBusySlots: 1 */
/*Endpoint 1 Descriptor*/
/*Endpoint IN1 Descriptor*/
7, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x81, /* bEndpointAddress: (IN1) */
0x02, /* bmAttributes: Bulk */
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
0x00, /* bInterval */
/*Endpoint 2 Descriptor*/
/*Endpoint OUT1 Descriptor*/
7, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x02, /* bEndpointAddress: (OUT2) */
0x01, /* bEndpointAddress: (OUT1) */
0x02, /* bmAttributes: Bulk */
USB_ICC_DATA_SIZE, 0x00, /* wMaxPacketSize: */
0x00, /* bInterval */
@@ -193,7 +208,40 @@ static const uint8_t gnukConfigDescriptor[] = {
0x83, /* bEndpointAddress: (IN3) */
0x02, /* bmAttributes: Bulk */
VIRTUAL_COM_PORT_DATA_SIZE, 0x00, /* wMaxPacketSize: */
0x00 /* bInterval */
0x00, /* bInterval */
#endif
#ifdef PINPAD_DND_SUPPORT
/* Interface Descriptor.*/
9, /* bLength: Interface Descriptor size */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType: Interface */
#ifdef ENABLE_VIRTUAL_COM_PORT
0x03, /* bInterfaceNumber. */
#else
0x01, /* bInterfaceNumber. */
#endif
0x00, /* bAlternateSetting. */
0x02, /* bNumEndpoints. */
0x08, /* bInterfaceClass (Mass Stprage). */
0x06, /* bInterfaceSubClass (SCSI
transparent command set, MSCO
chapter 2). */
0x50, /* bInterfaceProtocol (Bulk-Only
Mass Storage, MSCO chapter 3). */
0x00, /* iInterface. */
/* Endpoint Descriptor.*/
7, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x86, /* bEndpointAddress: (IN6) */
0x02, /* bmAttributes (Bulk). */
0x40, 0x00, /* wMaxPacketSize. */
0x00, /* bInterval (ignored for bulk). */
/* Endpoint Descriptor.*/
7, /* bLength: Endpoint Descriptor size */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType: Endpoint */
0x06, /* bEndpointAddress: (OUT6) */
0x02, /* bmAttributes (Bulk). */
0x40, 0x00, /* wMaxPacketSize. */
0x00, /* bInterval (ignored for bulk). */
#endif
};
@@ -205,48 +253,33 @@ static const uint8_t gnukStringLangID[] = {
0x09, 0x04 /* LangID = 0x0409: US-English */
};
static const uint8_t gnukStringVendor[] = {
33*2+2, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType*/
/* Manufacturer: "Free Software Initiative of Japan" */
'F', 0, 'r', 0, 'e', 0, 'e', 0, ' ', 0, 'S', 0, 'o', 0, 'f', 0,
't', 0, 'w', 0, 'a', 0, 'r', 0, 'e', 0, ' ', 0, 'I', 0, 'n', 0,
'i', 0, 't', 0, 'i', 0, 'a', 0, 't', 0, 'i', 0, 'v', 0, 'e', 0,
' ', 0, 'o', 0, 'f', 0, ' ', 0, 'J', 0, 'a', 0, 'p', 0, 'a', 0,
'n', 0
};
static const uint8_t gnukStringProduct[] = {
14*2+2, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
/* Product name: "FSIJ USB Token" */
'F', 0, 'S', 0, 'I', 0, 'J', 0, ' ', 0, 'U', 0, 'S', 0, 'B', 0,
' ', 0, 'T', 0, 'o', 0, 'k', 0, 'e', 0, 'n', 0
};
#include "usb-string-vendor-product.c.inc"
const uint8_t gnukStringSerial[] = {
13*2+2, /* bLength */
18*2+2, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'0', 0, '.', 0, '1', 0, '3', 0, /* Version number of Gnuk */
/* FSIJ-0.18 */
'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0,
'0', 0, '.', 0, '1', 0, '8', 0, /* Version number of Gnuk */
'-', 0,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
};
const ONE_DESCRIPTOR Device_Descriptor = {
(uint8_t*)gnukDeviceDescriptor,
const struct Descriptor Device_Descriptor = {
gnukDeviceDescriptor,
sizeof (gnukDeviceDescriptor)
};
const ONE_DESCRIPTOR Config_Descriptor = {
(uint8_t*)gnukConfigDescriptor,
const struct Descriptor Config_Descriptor = {
gnukConfigDescriptor,
sizeof (gnukConfigDescriptor)
};
const ONE_DESCRIPTOR String_Descriptor[] = {
{(uint8_t*)gnukStringLangID, sizeof (gnukStringLangID)},
{(uint8_t*)gnukStringVendor, sizeof (gnukStringVendor)},
{(uint8_t*)gnukStringProduct, sizeof (gnukStringProduct)},
{(uint8_t*)gnukStringSerial, sizeof (gnukStringSerial)},
const struct Descriptor String_Descriptors[NUM_STRING_DESC] = {
{gnukStringLangID, sizeof (gnukStringLangID)},
{gnukStringVendor, sizeof (gnukStringVendor)},
{gnukStringProduct, sizeof (gnukStringProduct)},
{gnukStringSerial, sizeof (gnukStringSerial)},
};

View File

@@ -1,22 +0,0 @@
/*
* Virtual COM port (for debug output only)
*/
#include "usb_lib.h"
#include "config.h"
#include "ch.h"
#include "gnuk.h"
void
EP3_IN_Callback(void)
{
if (stdout_thread)
chEvtSignalI (stdout_thread, EV_TX_READY);
}
void
EP5_OUT_Callback(void)
{
SetEPRxValid (ENDP3);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +1,143 @@
#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
#define USB_STRING_DESCRIPTOR_TYPE 0x03
#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
#define STANDARD_ENDPOINT_DESC_SIZE 0x09
/* endpoints enumeration */
#define ENDP0 ((uint8_t)0)
#define ENDP1 ((uint8_t)1)
#define ENDP2 ((uint8_t)2)
#define ENDP3 ((uint8_t)3)
#define ENDP4 ((uint8_t)4)
#define ENDP5 ((uint8_t)5)
#define ENDP6 ((uint8_t)6)
#define ENDP7 ((uint8_t)7)
/* EP_TYPE[1:0] EndPoint TYPE */
#define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
enum RECIPIENT_TYPE
{
DEVICE_RECIPIENT, /* Recipient device */
INTERFACE_RECIPIENT, /* Recipient interface */
ENDPOINT_RECIPIENT, /* Recipient endpoint */
OTHER_RECIPIENT
};
enum DESCRIPTOR_TYPE
{
DEVICE_DESCRIPTOR = 1,
CONFIG_DESCRIPTOR,
STRING_DESCRIPTOR,
INTERFACE_DESCRIPTOR,
ENDPOINT_DESCRIPTOR
};
#define REQUEST_TYPE 0x60 /* Mask to get request type */
#define STANDARD_REQUEST 0x00 /* Standard request */
#define CLASS_REQUEST 0x20 /* Class request */
#define VENDOR_REQUEST 0x40 /* Vendor request */
struct Descriptor
{
const uint8_t *Descriptor;
uint16_t Descriptor_Size;
};
enum
{
USB_UNSUPPORT = 0,
USB_SUCCESS = 1,
};
struct usb_device_method
{
void (*init) (void);
void (*reset) (void);
void (*setup_with_data) (uint8_t rcp, uint8_t req_no, uint16_t index);
int (*setup_with_nodata) (uint8_t rcp, uint8_t req_no, uint16_t index);
int (*get_descriptor) (uint8_t desc_type, uint16_t index, uint16_t value);
int (*event) (uint8_t event_type, uint16_t value);
int (*interface) (uint8_t cmd, uint16_t interface, uint16_t value);
};
enum {
USB_EVENT_RESET,
USB_EVENT_ADDRESS,
USB_EVENT_CONFIG,
USB_EVENT_SUSPEND,
USB_EVENT_WAKEUP,
USB_EVENT_STALL,
};
enum {
USB_SET_INTERFACE,
USB_GET_INTERFACE,
USB_QUERY_INTERFACE,
};
extern void USB_Cable_Config (int NewState);
extern const struct usb_device_method Device_Method;
extern const struct Descriptor Device_Descriptor;
extern const struct Descriptor Config_Descriptor;
extern const struct Descriptor String_Descriptors[];
enum DEVICE_STATE
{
UNCONNECTED,
ATTACHED,
POWERED,
SUSPENDED,
ADDRESSED,
CONFIGURED
};
extern uint32_t bDeviceState;
#define STM32_USB_IRQ_PRIORITY 11
void usb_lld_init (void);
extern void usb_lld_init (void);
extern void usb_lld_to_pmabuf (const void *src, uint16_t addr, size_t n);
extern void usb_lld_from_pmabuf (void *dst, uint16_t addr, size_t n);
extern void usb_lld_stall_tx (int ep_num);
extern void usb_lld_stall_rx (int ep_num);
extern int usb_lld_tx_data_len (int ep_num);
extern void usb_lld_txcpy (const void *src, int ep_num, int offset, size_t len);
extern void usb_lld_tx_enable (int ep_num, size_t len);
extern void usb_lld_write (uint8_t ep_num, const void *buf, size_t len);
extern void usb_lld_rx_enable (int ep_num);
extern int usb_lld_rx_data_len (int ep_num);
extern void usb_lld_rxcpy (uint8_t *dst, int ep_num, int offset, size_t len);
extern void usb_lld_reset (void);
extern void usb_lld_setup_endpoint (int ep_num, int ep_type, int ep_kind,
int ep_rx_addr, int ep_tx_addr,
int ep_rx_memory_size);
extern void usb_lld_set_configuration (uint8_t config);
extern uint8_t usb_lld_current_configuration (void);
extern void usb_lld_set_feature (uint8_t feature);
extern void usb_lld_set_data_to_send (const void *p, size_t len);

View File

@@ -1,7 +1,7 @@
/*
* usb_prop.c - glue/interface code between Gnuk and USB-FS-Device_Lib
* usb_prop.c - interface code between Gnuk and USB
*
* Copyright (C) 2010, 2011 Free Software Initiative of Japan
* Copyright (C) 2010, 2011, 2012 Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -25,262 +25,177 @@
#define GNUK_MAX_PACKET_SIZE 64
#include "config.h"
#include "usb_lib.h"
#include "ch.h"
#include "usb_lld.h"
#include "usb_conf.h"
#include "usb_prop.h"
#include "usb_desc.h"
#include "usb_pwr.h"
#include "hw_config.h"
#ifdef ENABLE_VIRTUAL_COM_PORT
#include "usb-cdc-vport.c"
#include "usb-cdc.h"
struct line_coding
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
};
static const struct line_coding line_coding = {
115200, /* baud rate: 115200 */
0x00, /* stop bits: 1 */
0x00, /* parity: none */
0x08 /* bits: 8 */
};
static void
vcom_port_data_setup (uint8_t RequestNo)
{
if (RequestNo != USB_CDC_REQ_GET_LINE_CODING)
return;
/* RequestNo == USB_CDC_REQ_SET_LINE_CODING is not supported */
usb_lld_set_data_to_send (&line_coding, sizeof(line_coding));
}
static int
vcom_port_setup_with_nodata (uint8_t RequestNo)
{
if (RequestNo == USB_CDC_REQ_SET_CONTROL_LINE_STATE)
/* Do nothing and success */
return USB_SUCCESS;
return USB_UNSUPPORT;
}
#define VCOM_NUM_INTERFACES 2
#else
#define VCOM_NUM_INTERFACES 0
#endif
#ifdef PINPAD_DND_SUPPORT
#include "usb-msc.h"
#define MSC_NUM_INTERFACES 1
#else
#define MSC_NUM_INTERFACES 0
#endif
#define NUM_INTERFACES (1+VCOM_NUM_INTERFACES+MSC_NUM_INTERFACES)
#define MSC_INTERFACE_NO (1+VCOM_NUM_INTERFACES)
uint32_t bDeviceState = UNCONNECTED; /* USB device status */
static void
gnuk_device_init (void)
{
pInformation->Current_Configuration = 0;
/* Connect the device */
PowerOn ();
/* Perform basic device initialization operations */
USB_SIL_Init ();
usb_lld_set_configuration (0);
USB_Cable_Config (1);
bDeviceState = UNCONNECTED;
}
static void
gnuk_setup_endpoints_for_interface (uint16_t interface)
{
if (interface == 0)
{
/* Initialize Endpoint 1 */
usb_lld_setup_endpoint (ENDP1, EP_BULK, 0, ENDP1_RXADDR, ENDP1_TXADDR,
GNUK_MAX_PACKET_SIZE);
}
#ifdef ENABLE_VIRTUAL_COM_PORT
else if (interface == 1)
{
/* Initialize Endpoint 4 */
usb_lld_setup_endpoint (ENDP4, EP_INTERRUPT, 0, 0, ENDP4_TXADDR, 0);
}
else if (interface == 2)
{
/* Initialize Endpoint 3 */
usb_lld_setup_endpoint (ENDP3, EP_BULK, 0, 0, ENDP3_TXADDR, 0);
/* Initialize Endpoint 5 */
usb_lld_setup_endpoint (ENDP5, EP_BULK, 0, ENDP5_RXADDR, 0,
VIRTUAL_COM_PORT_DATA_SIZE);
}
#endif
#ifdef PINPAD_DND_SUPPORT
else if (interface == MSC_INTERFACE_NO)
{
/* Initialize Endpoint 6 */
usb_lld_setup_endpoint (ENDP6, EP_BULK, 0, ENDP6_RXADDR, ENDP6_TXADDR,
64);
usb_lld_stall_rx (ENDP6);
}
#endif
}
static void
gnuk_device_reset (void)
{
int i;
/* Set DEVICE as not configured */
pInformation->Current_Configuration = 0;
usb_lld_set_configuration (0);
/* Current Feature initialization */
pInformation->Current_Feature = Config_Descriptor.Descriptor[7];
usb_lld_set_feature (Config_Descriptor.Descriptor[7]);
/* Set DEVICE with the default Interface*/
pInformation->Current_Interface = 0;
SetBTABLE (BTABLE_ADDRESS);
usb_lld_reset ();
/* Initialize Endpoint 0 */
SetEPType (ENDP0, EP_CONTROL);
SetEPTxStatus (ENDP0, EP_TX_STALL);
SetEPRxAddr (ENDP0, ENDP0_RXADDR);
SetEPTxAddr (ENDP0, ENDP0_TXADDR);
Clear_Status_Out (ENDP0);
SetEPRxCount (ENDP0, GNUK_MAX_PACKET_SIZE);
SetEPRxValid (ENDP0);
usb_lld_setup_endpoint (ENDP0, EP_CONTROL, 0, ENDP0_RXADDR, ENDP0_TXADDR,
GNUK_MAX_PACKET_SIZE);
/* Initialize Endpoint 1 */
SetEPType (ENDP1, EP_BULK);
SetEPTxAddr (ENDP1, ENDP1_TXADDR);
SetEPTxStatus (ENDP1, EP_TX_NAK);
SetEPRxStatus (ENDP1, EP_RX_DIS);
/* Initialize Endpoint 2 */
SetEPType (ENDP2, EP_BULK);
SetEPRxAddr (ENDP2, ENDP2_RXADDR);
SetEPRxCount (ENDP2, GNUK_MAX_PACKET_SIZE);
SetEPRxStatus (ENDP2, EP_RX_VALID);
SetEPTxStatus (ENDP2, EP_TX_DIS);
#ifdef ENABLE_VIRTUAL_COM_PORT
/* Initialize Endpoint 3 */
SetEPType (ENDP3, EP_BULK);
SetEPTxAddr (ENDP3, ENDP3_TXADDR);
SetEPTxStatus (ENDP3, EP_TX_NAK);
SetEPRxStatus (ENDP3, EP_RX_DIS);
/* Initialize Endpoint 4 */
SetEPType (ENDP4, EP_INTERRUPT);
SetEPTxAddr (ENDP4, ENDP4_TXADDR);
SetEPTxStatus (ENDP4, EP_TX_NAK);
SetEPRxStatus (ENDP4, EP_RX_DIS);
/* Initialize Endpoint 5 */
SetEPType (ENDP5, EP_BULK);
SetEPRxAddr (ENDP5, ENDP5_RXADDR);
SetEPRxCount (ENDP5, VIRTUAL_COM_PORT_DATA_SIZE);
SetEPRxStatus (ENDP5, EP_RX_VALID);
SetEPTxStatus (ENDP5, EP_TX_DIS);
#endif
/* Set this device to response on default address */
SetDeviceAddress (0);
for (i = 0; i < NUM_INTERFACES; i++)
gnuk_setup_endpoints_for_interface (i);
bDeviceState = ATTACHED;
}
static void
gnuk_device_SetConfiguration (void)
{
DEVICE_INFO *pInfo = &Device_Info;
if (pInfo->Current_Configuration != 0)
/* Device configured */
bDeviceState = CONFIGURED;
}
static void
gnuk_device_SetInterface (void)
{
uint16_t intf = pInformation->USBwIndex0;
/* alternateSetting: pInformation->USBwValue0 should be 0 */
if (intf == 0)
{
ClearDTOG_RX (ENDP2);
ClearDTOG_TX (ENDP1);
}
#ifdef ENABLE_VIRTUAL_COM_PORT
else if (intf == 1)
{
ClearDTOG_TX (ENDP4);
}
else if (intf == 2)
{
ClearDTOG_RX (ENDP5);
ClearDTOG_TX (ENDP3);
}
#endif
}
static void
gnuk_device_SetDeviceAddress (void)
{
bDeviceState = ADDRESSED;
}
/* IN from port 0 */
static void
gnuk_device_Status_In (void)
{
}
/* OUT to port 0 */
static void
gnuk_device_Status_Out (void)
{
}
static uint8_t *
gnuk_device_GetDeviceDescriptor (uint16_t Length)
{
return Standard_GetDescriptorData (Length,
(PONE_DESCRIPTOR)&Device_Descriptor);
}
static uint8_t *
gnuk_device_GetConfigDescriptor (uint16_t Length)
{
return Standard_GetDescriptorData (Length,
(PONE_DESCRIPTOR)&Config_Descriptor);
}
static uint8_t *
gnuk_device_GetStringDescriptor (uint16_t Length)
{
uint8_t wValue0 = pInformation->USBwValue0;
if (wValue0 >= (sizeof (String_Descriptor) / sizeof (ONE_DESCRIPTOR)))
return NULL;
else
return
Standard_GetDescriptorData (Length,
(PONE_DESCRIPTOR)&String_Descriptor[wValue0]);
}
#ifdef ENABLE_VIRTUAL_COM_PORT
#define NUM_INTERFACES 3 /* two for CDC, one for CCID */
#else
#define NUM_INTERFACES 1 /* CCID only */
#endif
static RESULT
gnuk_device_Get_Interface_Setting (uint8_t Interface, uint8_t AlternateSetting)
{
if (AlternateSetting > 0) /* Any interface, we have no alternate */
return USB_UNSUPPORT;
else if (Interface > NUM_INTERFACES)
return USB_UNSUPPORT;
return USB_SUCCESS;
}
#define USB_CCID_REQ_ABORT 0x01
#define USB_CCID_REQ_GET_CLOCK_FREQUENCIES 0x02
#define USB_CCID_REQ_GET_DATA_RATES 0x03
static const uint8_t freq_table[] = { 0xf3, 0x0d, 0, 0, }; /* dwDefaultClock */
static uint8_t *
gnuk_clock_frequencies (uint16_t len)
{
if (len == 0)
{
pInformation->Ctrl_Info.Usb_wLength = sizeof (freq_table);
return NULL;
}
return (uint8_t *)freq_table;
}
static const uint8_t data_rate_table[] = { 0x80, 0x25, 0, 0, }; /* dwDataRate */
static uint8_t *
gnuk_data_rates (uint16_t len)
{
if (len == 0)
{
pInformation->Ctrl_Info.Usb_wLength = sizeof (data_rate_table);
return NULL;
}
return (uint8_t *)data_rate_table;
}
static RESULT
gnuk_setup_with_data (uint8_t RequestNo)
{
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
if (pInformation->USBwIndex0 == 0) /* Interface */
{
if (RequestNo == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
{
pInformation->Ctrl_Info.CopyData = gnuk_clock_frequencies;
pInformation->Ctrl_Info.Usb_wOffset = 0;
gnuk_clock_frequencies (0);
return USB_SUCCESS;
}
else if (RequestNo == USB_CCID_REQ_GET_DATA_RATES)
{
pInformation->Ctrl_Info.CopyData = gnuk_data_rates;
pInformation->Ctrl_Info.Usb_wOffset = 0;
gnuk_data_rates (0);
return USB_SUCCESS;
}
else
return USB_UNSUPPORT;
}
else
{
#if defined(ENABLE_VIRTUAL_COM_PORT)
return Virtual_Com_Port_Data_Setup (RequestNo);
#else
return USB_UNSUPPORT;
#if defined(PINPAD_DND_SUPPORT)
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
#endif
}
else
return USB_UNSUPPORT;
static void
gnuk_setup_with_data (uint8_t recipient, uint8_t RequestNo, uint16_t index)
{
if (recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) /* Interface */
{
if (index == 0)
{
if (RequestNo == USB_CCID_REQ_GET_CLOCK_FREQUENCIES)
usb_lld_set_data_to_send (freq_table, sizeof (freq_table));
else if (RequestNo == USB_CCID_REQ_GET_DATA_RATES)
usb_lld_set_data_to_send (data_rate_table, sizeof (data_rate_table));
}
#ifdef ENABLE_VIRTUAL_COM_PORT
else if (index == 1)
vcom_port_data_setup (RequestNo);
#endif
#ifdef PINPAD_DND_SUPPORT
else if (index == MSC_INTERFACE_NO)
{
if (RequestNo == MSC_GET_MAX_LUN_COMMAND)
usb_lld_set_data_to_send (lun_table, sizeof (lun_table));
}
#endif
}
}
static RESULT
gnuk_setup_with_nodata (uint8_t RequestNo)
static int
gnuk_setup_with_nodata (uint8_t recipient, uint8_t RequestNo, uint16_t index)
{
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
if (pInformation->USBwIndex0 == 0) /* Interface */
if (recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) /* Interface */
if (index == 0)
{
if (RequestNo == USB_CCID_REQ_ABORT)
/* wValue: bSeq, bSlot */
@@ -289,50 +204,139 @@ gnuk_setup_with_nodata (uint8_t RequestNo)
else
return USB_UNSUPPORT;
}
else
{
#if defined(ENABLE_VIRTUAL_COM_PORT)
return Virtual_Com_Port_NoData_Setup (RequestNo);
#else
return USB_UNSUPPORT;
#ifdef ENABLE_VIRTUAL_COM_PORT
else if (index == 1)
return vcom_port_setup_with_nodata (RequestNo);
#endif
#ifdef PINPAD_DND_SUPPORT
else if (index == MSC_INTERFACE_NO)
{
if (RequestNo == MSC_MASS_STORAGE_RESET_COMMAND)
{
/* Should call resetting MSC thread, something like msc_reset() */
return USB_SUCCESS;
}
else
return USB_UNSUPPORT;
}
#endif
else
return USB_UNSUPPORT;
else
return USB_UNSUPPORT;
}
static int
gnuk_get_descriptor (uint8_t desc_type, uint16_t index, uint16_t value)
{
(void)index;
if (desc_type == DEVICE_DESCRIPTOR)
{
usb_lld_set_data_to_send (Device_Descriptor.Descriptor,
Device_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == CONFIG_DESCRIPTOR)
{
usb_lld_set_data_to_send (Config_Descriptor.Descriptor,
Config_Descriptor.Descriptor_Size);
return USB_SUCCESS;
}
else if (desc_type == STRING_DESCRIPTOR)
{
uint8_t desc_index = value & 0xff;
if (desc_index < NUM_STRING_DESC)
{
usb_lld_set_data_to_send (String_Descriptors[desc_index].Descriptor,
String_Descriptors[desc_index].Descriptor_Size);
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}
static int gnuk_usb_event (uint8_t event_type, uint16_t value)
{
switch (event_type)
{
case USB_EVENT_RESET:
break;
case USB_EVENT_ADDRESS:
bDeviceState = ADDRESSED;
break;
case USB_EVENT_CONFIG:
if (usb_lld_current_configuration () == 0)
{
int i;
extern void *main_thread;
#define LED_STATUS_MODE (8)
if (value != 1)
return USB_UNSUPPORT;
usb_lld_set_configuration (value);
for (i = 0; i < NUM_INTERFACES; i++)
gnuk_setup_endpoints_for_interface (i);
bDeviceState = CONFIGURED;
chEvtSignalI (main_thread, LED_STATUS_MODE);
return USB_SUCCESS;
}
else
{
if (value != 0)
return USB_UNSUPPORT;
usb_lld_set_configuration (0);
// Disable all endpoints???
bDeviceState = ADDRESSED;
}
default:
break;
}
return USB_UNSUPPORT;
}
static int gnuk_interface (uint8_t cmd, uint16_t interface, uint16_t alt)
{
static uint8_t zero = 0;
if (interface >= NUM_INTERFACES)
return USB_UNSUPPORT;
switch (cmd)
{
case USB_SET_INTERFACE:
if (alt != 0)
return USB_UNSUPPORT;
else
{
gnuk_setup_endpoints_for_interface (interface);
return USB_SUCCESS;
}
case USB_GET_INTERFACE:
usb_lld_set_data_to_send (&zero, 1);
return USB_SUCCESS;
default:
case USB_QUERY_INTERFACE:
return USB_SUCCESS;
}
}
/*
* Interface to USB core
*/
const DEVICE_PROP Device_Property = {
const struct usb_device_method Device_Method = {
gnuk_device_init,
gnuk_device_reset,
gnuk_device_Status_In,
gnuk_device_Status_Out,
gnuk_setup_with_data,
gnuk_setup_with_nodata,
gnuk_device_Get_Interface_Setting,
gnuk_device_GetDeviceDescriptor,
gnuk_device_GetConfigDescriptor,
gnuk_device_GetStringDescriptor,
0,
GNUK_MAX_PACKET_SIZE
};
const DEVICE Device_Table = {
EP_NUM,
1
};
const USER_STANDARD_REQUESTS User_Standard_Requests = {
NOP_Process, /* GetConfiguration */
gnuk_device_SetConfiguration,
NOP_Process, /* GetInterface */
gnuk_device_SetInterface,
NOP_Process, /* GetStatus */
NOP_Process, /* ClearFeature */
NOP_Process, /* SetEndPointFeature */
NOP_Process, /* SetDeviceFeature */
gnuk_device_SetDeviceAddress
gnuk_get_descriptor,
gnuk_usb_event,
gnuk_interface,
};

View File

@@ -1,7 +0,0 @@
#ifndef __usb_prop_H
#define __usb_prop_H
extern const ONE_DESCRIPTOR Device_Descriptor;
extern const ONE_DESCRIPTOR Config_Descriptor;
extern const ONE_DESCRIPTOR String_Descriptor[4];
#endif /* __usb_prop_H */

View File

@@ -1,5 +0,0 @@
VCOMDIR = ../Virtual_COM_Port
VCOMSRC= $(VCOMDIR)/usb_istr.c $(VCOMDIR)/usb_pwr.c
ifneq ($(ENABLE_VCOMPORT),)
VCOMSRC += usb_endp.c
endif

View File

@@ -4,7 +4,7 @@
dfuse.py - DFU (Device Firmware Upgrade) tool for STM32 Processor.
"SE" in DfuSe stands for "STmicroelectronics Extention".
Copyright (C) 2010 Free Software Initiative of Japan
Copyright (C) 2010, 2011 Free Software Initiative of Japan
Author: NIIBE Yutaka <gniibe@fsij.org>
This file is a part of Gnuk, a GnuPG USB Token implementation.
@@ -208,10 +208,23 @@ class DFU_STM32:
# First, erase pages
sys.stdout.write("Erasing: ")
sys.stdout.flush()
last_addr = 0
for start_addr in sorted(ih.memory.keys()):
data = ih.memory[start_addr]
end_addr = start_addr + len(data)
addr = start_addr & 0xfffffc00
if not last_addr == 0:
i = 0
if last_addr > addr:
addr = last_addr
else:
while last_addr < addr:
self.dfuse_erase(last_addr)
if i & 0x03 == 0x03:
sys.stdout.write(".")
sys.stdout.flush()
last_addr += 1024
i += 1
i = 0
while addr < end_addr:
self.dfuse_erase(addr)
@@ -220,20 +233,32 @@ class DFU_STM32:
sys.stdout.flush()
addr += 1024
i += 1
last_addr = addr
sys.stdout.write("\n")
sys.stdout.flush()
# Then, write pages
sys.stdout.write("Writing: ")
sys.stdout.flush()
last_addr = 0
for start_addr in sorted(ih.memory.keys()):
data = ih.memory[start_addr]
end_addr = start_addr + len(data)
addr = start_addr & 0xfffffc00
# XXX: data should be 1-KiB aligned
if addr != start_addr:
raise ValueError, "padding is not supported yet"
self.dfuse_set_address_pointer(addr)
if not last_addr == 0:
i = 0
while last_addr < addr:
if i & 0x03 == 0x03:
sys.stdout.write(".")
sys.stdout.flush()
last_addr += 1024
i += 1
i = 0
if addr != start_addr:
self.dfuse_set_address_pointer(start_addr)
self.dfuse_write_memory(data[0:(addr + 1024 - start_addr)])
data = data[(addr + 1024 - start_addr):]
addr += 1024
self.dfuse_set_address_pointer(addr)
while addr < end_addr:
self.dfuse_write_memory(data[i*1024:(i+1)*1024])
if i & 0x03 == 0x03:
@@ -241,6 +266,7 @@ class DFU_STM32:
sys.stdout.flush()
addr += 1024
i += 1
last_addr = addr
if self.__protocol == DFU_STM32PROTOCOL_0:
# 0-length write at the end
self.ll_download_block(self.__blocknum, None)
@@ -268,13 +294,33 @@ class DFU_STM32:
# Read pages
sys.stdout.write("Reading: ")
sys.stdout.flush()
last_addr = 0
for start_addr in sorted(ih.memory.keys()):
data = ih.memory[start_addr]
end_addr = start_addr + len(data)
addr = start_addr & 0xfffffc00
# XXX: data should be 1-KiB aligned
if not last_addr == 0:
i = 0
while last_addr < addr:
if i & 0x03 == 0x03:
sys.stdout.write(".")
sys.stdout.flush()
last_addr += 1024
i += 1
if addr != start_addr:
raise ValueError, "padding is not supported yet"
self.dfuse_set_address_pointer(addr)
self.ll_clear_status()
self.ll_clear_status()
block = self.dfuse_read_memory()
j = 0
for c in data[0:(addr + 1024 - start_addr)]:
if (ord(c)&0xff) != block[j + start_addr - addr]:
raise ValueError, "verify failed at %08x" % (addr + i*1024+j)
j += 1
data = data[(addr + 1024 - start_addr):]
addr += 1024
self.ll_clear_status()
self.ll_clear_status()
self.dfuse_set_address_pointer(addr)
self.ll_clear_status()
self.ll_clear_status()
@@ -291,6 +337,7 @@ class DFU_STM32:
sys.stdout.flush()
addr += 1024
i += 1
last_addr = addr
self.ll_clear_status()
self.ll_clear_status()
self.ll_clear_status()

Some files were not shown because too many files have changed in this diff Show More