cuart icc clock freq and divider setting support
Change-Id: I9c99c68511d3972513348ee6be5e7bb3b3a5f99e
diff --git a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
index f9856f3..a8f8044 100644
--- a/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
+++ b/sysmoOCTSIM/cuart_driver_asf4_usart_async.c
@@ -289,6 +289,8 @@
cuart->u.asf4.usa_pd = usa_pd;
cuart->u.asf4.slot_nr = slot_nr;
+ /* in us, 20Mhz with default ncn8025 divider 8, F=372, D=1*/
+ cuart->u.asf4.extrawait_after_rx = 1./(20./8/372);
usart_async_register_callback(usa_pd, USART_ASYNC_RXC_CB, SIM_rx_cb[slot_nr]);
usart_async_register_callback(usa_pd, USART_ASYNC_TXC_CB, SIM_tx_cb[slot_nr]);
@@ -338,6 +340,8 @@
return io_read(&usa_pd->io, data, len);
}
+#include "ccid_device.h"
+#include "iso7816_3.h"
static int asf4_usart_ctrl(struct card_uart *cuart, enum card_uart_ctl ctl, int arg)
{
struct ncn8025_settings settings;
@@ -349,7 +353,7 @@
sercom->USART.CTRLB.bit.RXEN = 1;
sercom->USART.CTRLB.bit.TXEN = 0;
} else {
- delay_us(100);
+ delay_us(cuart->u.asf4.extrawait_after_rx);
sercom->USART.CTRLB.bit.RXEN = 0;
sercom->USART.CTRLB.bit.TXEN = 1;
}
@@ -361,22 +365,47 @@
usart_async_flush_rx_buffer(cuart->u.asf4.usa_pd);
break;
case CUART_CTL_POWER:
- ncn8025_get(cuart->u.asf4.slot_nr, &settings);
- settings.cmdvcc = arg ? true : false;
- settings.led = arg ? true : false;
- settings.vsel = SIM_VOLT_5V0;
+ /* in us, 20Mhz with default ncn8025 divider 8, F=372, D=1*/
+ cuart->u.asf4.extrawait_after_rx = 1./(20./8/372);
// set USART baud rate to match the interface (f = 2.5 MHz) and card default settings (Fd = 372, Dd = 1)
if(arg)
slot_set_isorate(cuart->u.asf4.slot_nr, SIM_CLKDIV_8, ISO7816_3_DEFAULT_FD, ISO7816_3_DEFAULT_DD);
+ ncn8025_get(cuart->u.asf4.slot_nr, &settings);
+ settings.cmdvcc = arg ? true : false;
+ settings.led = arg ? true : false;
+ settings.vsel = SIM_VOLT_5V0;
ncn8025_set(cuart->u.asf4.slot_nr, &settings);
+
break;
case CUART_CTL_WTIME:
/* no driver-specific handling of this */
break;
case CUART_CTL_CLOCK:
- /* FIXME */
+ /* no clock stop support */
+ break;
+ case CUART_CTL_CLOCK_FREQ:
+ ncn8025_get(cuart->u.asf4.slot_nr, &settings);
+
+ /* 2,5/5/10/20 supported by dividers */
+ enum ncn8025_sim_clkdiv clkdiv = SIM_CLKDIV_1;
+ if(arg < 20000000)
+ clkdiv = SIM_CLKDIV_2;
+ if(arg < 10000000)
+ clkdiv = SIM_CLKDIV_4;
+ if(arg < 5000000)
+ clkdiv = SIM_CLKDIV_8;
+ settings.clkdiv = clkdiv;
+ ncn8025_set(cuart->u.asf4.slot_nr, &settings);
+ break;
+ case CUART_CTL_FD:
+ ncn8025_get(cuart->u.asf4.slot_nr, &settings);
+ uint8_t divider = ncn8025_div_val[settings.clkdiv];
+ uint32_t baudrate = (20e6/divider)/arg;
+ cuart->u.asf4.extrawait_after_rx = 1./baudrate * 1000 * 1000;
+ slot_set_baudrate(cuart->u.asf4.slot_nr, baudrate);
+ break;
default:
return -EINVAL;
}