diff options
author | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2008-03-15 04:29:10 +0000 |
---|---|---|
committer | henryk <henryk@6dc7ffe9-61d6-0310-9af1-9938baff3ed1> | 2008-03-15 04:29:10 +0000 |
commit | 625ffcb32a947cbcf66b491f1f0ddd49d31c0a5e (patch) | |
tree | 50df40dd8fd1100b9d5b0cc42063c74d5f84ab62 | |
parent | 8ad8a1ea8800ea4cc6a2c74b24ce8bf867d8a906 (diff) |
Fix the clock gating for the new layer 2 code
Only perform the switch to continous when necessary since it has serious side effects in the current hardware (we really need TF ored into the clock gating)
git-svn-id: https://svn.openpcd.org:2342/trunk@457 6dc7ffe9-61d6-0310-9af1-9938baff3ed1
-rw-r--r-- | openpicc/application/iso14443_layer2a.c | 3 | ||||
-rw-r--r-- | openpicc/application/ssc.c | 37 |
2 files changed, 33 insertions, 7 deletions
diff --git a/openpicc/application/iso14443_layer2a.c b/openpicc/application/iso14443_layer2a.c index 2288eaa..2c2de3a 100644 --- a/openpicc/application/iso14443_layer2a.c +++ b/openpicc/application/iso14443_layer2a.c @@ -263,6 +263,9 @@ int iso14443_layer2a_init(u_int8_t enable_fast_receive) tc_cdiv_init(); tc_fdt_init(); + tc_cdiv_sync_init(); + tc_cdiv_sync_enable(); + clock_switch_init(); load_mod_init(); diff --git a/openpicc/application/ssc.c b/openpicc/application/ssc.c index 78f2960..2c4d61e 100644 --- a/openpicc/application/ssc.c +++ b/openpicc/application/ssc.c @@ -55,7 +55,7 @@ struct _ssc_handle { AT91PS_PDC pdc; AT91PS_SSC ssc; u_int8_t rx_enabled, tx_enabled; - u_int8_t rx_running, tx_running; + u_int8_t rx_running, tx_running, tx_need_switching; }; static ssc_handle_t _ssc; @@ -233,10 +233,32 @@ static int __ramfunc _ssc_tx_irq(u_int32_t sr, portBASE_TYPE task_woken) usb_print_string_f("<",0); /* Also set SSC mode to continous - * FIXME BUG: This will somehow drop some samples or something on the SSC*/ - vLedSetGreen(0); - sh->ssc->SSC_TCMR = (sh->ssc->SSC_TCMR & ~AT91C_SSC_START) | AT91C_SSC_START_CONTINOUS; - vLedSetGreen(1); + * FIXME BUG: This will somehow add two samples on the SSC + * The abomination below is designed to find a pause in the outgoing modulation data + * (WARNING: Will only work with manchester, not with PSK) so that the SSC start type + * switch will happen during a time of no subcarrier modulation (in order to not + * upset the subcarrier). Still need to find a way to 'absorb' the extra two samples. */ + if(sh->tx_need_switching) { + vLedSetGreen(0); + int j = 0; +off_pre: + if(j++ > 100) goto out; + if(!AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_MOD_PWM)) { + goto off_pre; + } +on: + if(j++ > 100) goto out; + if(AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_MOD_PWM)) goto on; + int i=0; +off: + if(j++ > 100) goto out; + if(!AT91F_PIO_IsInputSet(AT91C_BASE_PIOA, OPENPICC_MOD_PWM)) { + if(i++ > 2) goto out; else goto off; + } else goto on; +out: + sh->ssc->SSC_TCMR = (sh->ssc->SSC_TCMR & ~AT91C_SSC_START) | AT91C_SSC_START_CONTINOUS; + vLedSetGreen(1); + } if(sh->callback) sh->callback(SSC_CALLBACK_TX_FRAME_BEGIN, NULL); @@ -659,7 +681,7 @@ int ssc_recv(ssc_handle_t* sh, ssc_dma_rx_buffer_t* *buffer,unsigned int timeout return -ETIMEDOUT; } - +extern u_int32_t fdt_offset; /* Must be called with IRQs disabled. E.g. from IRQ context or within a critical section. */ int ssc_send(ssc_handle_t* sh, ssc_dma_tx_buffer_t *buffer) { @@ -681,11 +703,12 @@ int ssc_send(ssc_handle_t* sh, ssc_dma_tx_buffer_t *buffer) int data_len = 32; int num_data = buffer->len/(data_len/8); /* FIXME This is broken for more than 64 bytes, or is it? */ int num_data_ssc = num_data > 16 ? 16 : num_data; + sh->tx_need_switching = (num_data > 16); sh->ssc->SSC_TFMR = ((data_len-1) & 0x1f) | (((num_data_ssc-1) & 0x0f) << 8) | (((sync_len-1) & 0x0f) << 16); - sh->ssc->SSC_TCMR = 0x01 | AT91C_SSC_CKO_NONE | AT91C_SSC_CKI | start_cond; + sh->ssc->SSC_TCMR = 0x01 | AT91C_SSC_CKO_NONE | (AT91C_SSC_CKI&0) | start_cond; AT91F_PDC_SetTx(sh->pdc, buffer->data, num_data); AT91F_PDC_SetNextTx(sh->pdc, 0, 0); |