diff --git a/ChangeLog b/ChangeLog index 74a37de..241e20b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2013-11-18 Niibe Yutaka + * regnual/sys.c (entry): Bug fix of clearing BSS. + + * src/usb_stm32f103.c: Update from NeuG. + (usb_handle_transfer): Add argument ISTR_VALUE. + * src/openpgp.c (card_thread): Add noinline attribute. * src/usb-icc.c (ccid_thread): Join the OpenPGP thread. diff --git a/regnual/sys.c b/regnual/sys.c index 8e0f528..6b8bfda 100644 --- a/regnual/sys.c +++ b/regnual/sys.c @@ -32,15 +32,19 @@ void entry (void) "subs r1, r1, #4\n\t" "bne 0b\n\t" /* Relocation done. */ + "add r0, r3\n\t" "ldr r3, .L00\n" ".LPIC00:\n\t" "add r3, pc\n\t" /* R3 := @_GLOBAL_OFFSET_TABLE_ */ - /* Clear BSS. */ - "mov r0, #0\n\t" + /* Compute the address of BSS. */ "ldr r4, .L00+4\n\t" "ldr r1, [r3, r4]\n\t" + "add r1, r0\n\t" /* relocate bss_start */ "ldr r4, .L00+8\n\t" "ldr r2, [r3, r4]\n" + "add r1, r0\n\t" /* relocate bss_end */ + /* Clear BSS. */ + "mov r0, #0\n\t" "0:\n\t" "str r0, [r1], #4\n\t" "cmp r2, r1\n\t" diff --git a/src/usb_stm32f103.c b/src/usb_stm32f103.c index dd33e67..2c946eb 100644 --- a/src/usb_stm32f103.c +++ b/src/usb_stm32f103.c @@ -93,8 +93,8 @@ static struct DATA_INFO *const data_p = &data_info; /* Buffer Table address register */ #define BTABLE ((volatile uint16_t *)(REG_BASE + 0x50)) -#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */ -#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */ +#define ISTR_CTR (0x8000) /* Correct TRansfer (read-only bit) */ +#define ISTR_OVR (0x4000) /* 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) */ @@ -105,8 +105,7 @@ static struct DATA_INFO *const data_p = &data_info; #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_OVR (~ISTR_OVR) /* clear 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 */ @@ -115,7 +114,7 @@ static struct DATA_INFO *const data_p = &data_info; #define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */ #define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */ -#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */ +#define CNTR_OVRM (0x4000) /* OVeR/underrun Mask */ #define CNTR_ERRM (0x2000) /* ERRor Mask */ #define CNTR_WKUPM (0x1000) /* WaKe UP Mask */ #define CNTR_SUSPM (0x0800) /* SUSPend Mask */ @@ -161,7 +160,7 @@ static struct DATA_INFO *const data_p = &data_info; #define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */ #define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */ -static void usb_handle_transfer (void); +static void usb_handle_transfer (uint16_t istr_value); static void st103_set_btable (void) { @@ -391,20 +390,22 @@ usb_interrupt_handler (void) { uint16_t istr_value = st103_get_istr (); - if (istr_value & ISTR_CTR) - usb_handle_transfer (); - - if (istr_value & ISTR_RESET) + if ((istr_value & ISTR_RESET)) { st103_set_istr (CLR_RESET); usb_cb_device_reset (); } + else + { + if ((istr_value & ISTR_OVR)) + st103_set_istr (CLR_OVR); - if (istr_value & ISTR_DOVR) - st103_set_istr (CLR_DOVR); + if ((istr_value & ISTR_ERR)) + st103_set_istr (CLR_ERR); - if (istr_value & ISTR_ERR) - st103_set_istr (CLR_ERR); + if ((istr_value & ISTR_CTR)) + usb_handle_transfer (istr_value); + } } static void handle_datastage_out (void) @@ -539,7 +540,7 @@ static int std_get_status (uint8_t req, uint8_t endpoint = (index & 0x0f); uint16_t status; - if ((index & 0x70) != 0 || endpoint == ENDP0) + if ((index & 0x70) || endpoint == ENDP0) return USB_UNSUPPORT; if ((index & 0x80)) @@ -932,80 +933,66 @@ void WEAK EP6_OUT_Callback (void); void WEAK EP7_OUT_Callback (void); static void -usb_handle_transfer (void) +usb_handle_transfer (uint16_t istr_value) { uint16_t ep_value = 0; - uint16_t istr_value; uint8_t ep_index; - while (((istr_value = st103_get_istr ()) & ISTR_CTR) != 0) + ep_index = (istr_value & ISTR_EP_ID); + /* Decode and service non control endpoints interrupt */ + /* process related endpoint register */ + ep_value = st103_get_epreg (ep_index); + + if (ep_index == 0) { - ep_index = (istr_value & ISTR_EP_ID); - if (ep_index == 0) + if ((ep_value & EP_CTR_TX)) { - if ((istr_value & ISTR_DIR) == 0) - { /* DIR = 0 */ - /* DIR = 0 => IN int */ - /* DIR = 0 implies that (EP_CTR_TX = 1) always */ - - st103_ep_clear_ctr_tx (ENDP0); - handle_in0 (); - } - else - { /* DIR = 1 */ - /* DIR = 1 & CTR_RX => SETUP or OUT int */ - /* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */ - - ep_value = st103_get_epreg (ENDP0); - if ((ep_value & EP_SETUP) != 0) - { - st103_ep_clear_ctr_rx (ENDP0); - handle_setup0 (); - } - else if ((ep_value & EP_CTR_RX) != 0) - { - st103_ep_clear_ctr_rx (ENDP0); - handle_out0 (); - } - } - - if (dev_p->state == STALLED) - st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_STALL); + st103_ep_clear_ctr_tx (ep_index); + handle_in0 (); } - else + + if ((ep_value & EP_CTR_RX)) { - /* Decode and service non control endpoints interrupt */ - /* process related endpoint register */ - ep_value = st103_get_epreg (ep_index); + st103_ep_clear_ctr_rx (ep_index); - if ((ep_value & EP_CTR_RX) != 0) + if ((ep_value & EP_SETUP)) + handle_setup0 (); + else + handle_out0 (); + } + + if (dev_p->state == STALLED) + st103_ep_set_rxtx_status (ENDP0, EP_RX_STALL, EP_TX_STALL); + } + else + { + if ((ep_value & EP_CTR_RX)) + { + st103_ep_clear_ctr_rx (ep_index); + switch ((ep_index - 1)) { - st103_ep_clear_ctr_rx (ep_index); - switch ((ep_index - 1)) - { - case 0: EP1_OUT_Callback (); break; - case 1: EP2_OUT_Callback (); break; - case 2: EP3_OUT_Callback (); break; - case 3: EP4_OUT_Callback (); break; - case 4: EP5_OUT_Callback (); break; - case 5: EP6_OUT_Callback (); break; - case 6: EP7_OUT_Callback (); break; - } + case 0: EP1_OUT_Callback (); break; + case 1: EP2_OUT_Callback (); break; + case 2: EP3_OUT_Callback (); break; + case 3: EP4_OUT_Callback (); break; + case 4: EP5_OUT_Callback (); break; + case 5: EP6_OUT_Callback (); break; + case 6: EP7_OUT_Callback (); break; } + } - if ((ep_value & EP_CTR_TX) != 0) + if ((ep_value & EP_CTR_TX)) + { + st103_ep_clear_ctr_tx (ep_index); + switch ((ep_index - 1)) { - st103_ep_clear_ctr_tx (ep_index); - switch ((ep_index - 1)) - { - case 0: EP1_IN_Callback (); break; - case 1: EP2_IN_Callback (); break; - case 2: EP3_IN_Callback (); break; - case 3: EP4_IN_Callback (); break; - case 4: EP5_IN_Callback (); break; - case 5: EP6_IN_Callback (); break; - case 6: EP7_IN_Callback (); break; - } + case 0: EP1_IN_Callback (); break; + case 1: EP2_IN_Callback (); break; + case 2: EP3_IN_Callback (); break; + case 3: EP4_IN_Callback (); break; + case 4: EP5_IN_Callback (); break; + case 5: EP6_IN_Callback (); break; + case 6: EP7_IN_Callback (); break; } } }