diff options
Diffstat (limited to 'firmware/target/arm/s5l8702/ipod6g')
-rw-r--r-- | firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c | 71 |
1 files changed, 42 insertions, 29 deletions
diff --git a/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c b/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c index b022fef675..c77b5d0c95 100644 --- a/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c +++ b/firmware/target/arm/s5l8702/ipod6g/serial-ipod6g.c | |||
@@ -18,19 +18,16 @@ | |||
18 | * KIND, either express or implied. | 18 | * KIND, either express or implied. |
19 | * | 19 | * |
20 | ****************************************************************************/ | 20 | ****************************************************************************/ |
21 | #include <stdio.h> | 21 | #include <stdint.h> |
22 | #include <stdlib.h> | 22 | #include <stdbool.h> |
23 | #include <stdarg.h> | ||
24 | 23 | ||
25 | #include "config.h" | 24 | #include "config.h" |
26 | #include "cpu.h" | 25 | #include "cpu.h" |
27 | #include "system.h" | 26 | #include "system.h" |
28 | #include "kernel.h" | ||
29 | |||
30 | #include "serial.h" | 27 | #include "serial.h" |
28 | |||
31 | #include "s5l8702.h" | 29 | #include "s5l8702.h" |
32 | #include "uc8702.h" | 30 | #include "uc870x.h" |
33 | #include "uart-s5l8702.h" | ||
34 | 31 | ||
35 | /* Define LOGF_ENABLE to enable logf output in this file */ | 32 | /* Define LOGF_ENABLE to enable logf output in this file */ |
36 | #define LOGF_ENABLE | 33 | #define LOGF_ENABLE |
@@ -38,16 +35,26 @@ | |||
38 | 35 | ||
39 | 36 | ||
40 | /* shall include serial HW configuracion for specific target */ | 37 | /* shall include serial HW configuracion for specific target */ |
41 | #define IPOD6G_UART_CLK_HZ 12000000 /* external OSC0 ??? */ | 38 | #define IPOD6G_UART_CLK_HZ 12000000 /* external OSC0 ??? */ |
39 | |||
40 | /* This values below are valid with a UCLK of 12MHz */ | ||
41 | #define BRDATA_9600 (77) /* 9615 */ | ||
42 | #define BRDATA_19200 (38) /* 19231 */ | ||
43 | #define BRDATA_28800 (25) /* 28846 */ | ||
44 | #define BRDATA_38400 (19 | (0xc330c << 8)) /* 38305 */ | ||
45 | #define BRDATA_57600 (12) /* 57692 */ | ||
46 | #define BRDATA_115200 (6 | (0xffffff << 8)) /* 114286 */ | ||
42 | 47 | ||
43 | extern struct uartc s5l8702_uart; | 48 | |
49 | extern const struct uartc s5l8702_uartc; | ||
44 | #ifdef IPOD_ACCESSORY_PROTOCOL | 50 | #ifdef IPOD_ACCESSORY_PROTOCOL |
45 | void iap_rx_isr(int, char*, char*, uint32_t); | 51 | void iap_rx_isr(int, char*, char*, uint32_t); |
46 | #endif | 52 | #endif |
47 | 53 | ||
48 | struct uartc_port ser_port IDATA_ATTR = { | 54 | struct uartc_port ser_port IDATA_ATTR = |
55 | { | ||
49 | /* location */ | 56 | /* location */ |
50 | .uartc = &s5l8702_uart, | 57 | .uartc = &s5l8702_uartc, |
51 | .id = 0, | 58 | .id = 0, |
52 | 59 | ||
53 | /* configuration */ | 60 | /* configuration */ |
@@ -70,17 +77,18 @@ struct uartc_port ser_port IDATA_ATTR = { | |||
70 | */ | 77 | */ |
71 | void serial_setup(void) | 78 | void serial_setup(void) |
72 | { | 79 | { |
73 | uart_port_init(&ser_port); | 80 | uartc_port_open(&ser_port); |
74 | 81 | ||
75 | /* set a default configuration, Tx and Rx modes are | 82 | /* set a default configuration, Tx and Rx modes are |
76 | disabled when the port is initialized */ | 83 | disabled when the port is initialized */ |
77 | uartc_port_config(&ser_port, 115200, ULCON_DATA_BITS_8, | 84 | uartc_port_config(&ser_port, ULCON_DATA_BITS_8, |
78 | ULCON_PARITY_NONE, ULCON_STOP_BITS_1); | 85 | ULCON_PARITY_NONE, ULCON_STOP_BITS_1); |
86 | uartc_port_set_bitrate_raw(&ser_port, BRDATA_115200); | ||
79 | 87 | ||
80 | /* enable Tx interrupt request or POLLING mode */ | 88 | /* enable Tx interrupt request or POLLING mode */ |
81 | uartc_port_set_tx_mode(&ser_port, UCON_MODE_INTREQ); | 89 | uartc_port_set_tx_mode(&ser_port, UCON_MODE_INTREQ); |
82 | 90 | ||
83 | logf("[%lu] serial_setup(): port %d ready!", USEC_TIMER, ser_port.id); | 91 | logf("[%lu] "MODEL_NAME" port %d ready!", USEC_TIMER, ser_port.id); |
84 | } | 92 | } |
85 | 93 | ||
86 | int tx_rdy(void) | 94 | int tx_rdy(void) |
@@ -93,16 +101,15 @@ void tx_writec(unsigned char c) | |||
93 | uartc_port_tx_byte(&ser_port, c); | 101 | uartc_port_tx_byte(&ser_port, c); |
94 | } | 102 | } |
95 | 103 | ||
104 | |||
96 | #ifdef IPOD_ACCESSORY_PROTOCOL | 105 | #ifdef IPOD_ACCESSORY_PROTOCOL |
97 | #include "iap.h" | 106 | #include "iap.h" |
98 | 107 | ||
99 | enum { | 108 | static enum { |
100 | ABR_STATUS_LAUNCHED, /* ST_SYNC */ | 109 | ABR_STATUS_LAUNCHED, /* ST_SYNC */ |
101 | ABR_STATUS_SYNCING, /* ST_SOF */ | 110 | ABR_STATUS_SYNCING, /* ST_SOF */ |
102 | ABR_STATUS_DONE | 111 | ABR_STATUS_DONE |
103 | }; | 112 | } abr_status; |
104 | |||
105 | int abr_status; | ||
106 | 113 | ||
107 | void serial_bitrate(int rate) | 114 | void serial_bitrate(int rate) |
108 | { | 115 | { |
@@ -131,8 +138,13 @@ void serial_bitrate(int rate) | |||
131 | abr_status = ABR_STATUS_LAUNCHED; | 138 | abr_status = ABR_STATUS_LAUNCHED; |
132 | } | 139 | } |
133 | else { | 140 | else { |
141 | uint32_t brdata; | ||
142 | if (rate == 57600) brdata = BRDATA_57600; | ||
143 | else if (rate == 38400) brdata = BRDATA_38400; | ||
144 | else if (rate == 19200) brdata = BRDATA_19200; | ||
145 | else brdata = BRDATA_9600; | ||
134 | uartc_port_abr_stop(&ser_port); /* abort ABR if already launched */ | 146 | uartc_port_abr_stop(&ser_port); /* abort ABR if already launched */ |
135 | uartc_port_set_bitrate(&ser_port, rate); | 147 | uartc_port_set_bitrate_raw(&ser_port, brdata); |
136 | uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); | 148 | uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); |
137 | abr_status = ABR_STATUS_DONE; | 149 | abr_status = ABR_STATUS_DONE; |
138 | } | 150 | } |
@@ -149,22 +161,21 @@ void iap_rx_isr(int len, char *data, char *err, uint32_t abr_cnt) | |||
149 | /* autobauding */ | 161 | /* autobauding */ |
150 | if (abr_cnt) { | 162 | if (abr_cnt) { |
151 | #define BR2CNT(s) (IPOD6G_UART_CLK_HZ / (unsigned)(s)) | 163 | #define BR2CNT(s) (IPOD6G_UART_CLK_HZ / (unsigned)(s)) |
152 | unsigned speed; | ||
153 | |||
154 | if (abr_cnt < BR2CNT(57600*1.1) || abr_cnt > BR2CNT(9600*0.9)) { | 164 | if (abr_cnt < BR2CNT(57600*1.1) || abr_cnt > BR2CNT(9600*0.9)) { |
155 | /* detected speed out of range, relaunch ABR */ | 165 | /* detected speed out of range, relaunch ABR */ |
156 | uartc_port_abr_start(&ser_port); | 166 | uartc_port_abr_start(&ser_port); |
157 | return; | 167 | return; |
158 | } | 168 | } |
159 | /* valid speed detected, select it */ | 169 | /* valid speed detected, select it */ |
160 | else if (abr_cnt < BR2CNT(48000)) speed = 57600; | 170 | uint32_t brdata; |
161 | else if (abr_cnt < BR2CNT(33600)) speed = 38400; | 171 | if (abr_cnt < BR2CNT(48000)) brdata = BRDATA_57600; |
162 | else if (abr_cnt < BR2CNT(24000)) speed = 28800; | 172 | else if (abr_cnt < BR2CNT(33600)) brdata = BRDATA_38400; |
163 | else if (abr_cnt < BR2CNT(14400)) speed = 19200; | 173 | else if (abr_cnt < BR2CNT(24000)) brdata = BRDATA_28800; |
164 | else speed = 9600; | 174 | else if (abr_cnt < BR2CNT(14400)) brdata = BRDATA_19200; |
175 | else brdata = BRDATA_9600; | ||
165 | 176 | ||
166 | /* set detected speed */ | 177 | /* set detected speed */ |
167 | uartc_port_set_bitrate(&ser_port, speed); | 178 | uartc_port_set_bitrate_raw(&ser_port, brdata); |
168 | uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); | 179 | uartc_port_set_rx_mode(&ser_port, UCON_MODE_INTREQ); |
169 | 180 | ||
170 | /* enter SOF state */ | 181 | /* enter SOF state */ |
@@ -176,10 +187,12 @@ void iap_rx_isr(int len, char *data, char *err, uint32_t abr_cnt) | |||
176 | } | 187 | } |
177 | 188 | ||
178 | /* process received data */ | 189 | /* process received data */ |
179 | while (len--) { | 190 | while (len--) |
191 | { | ||
180 | bool sync_done = !iap_getc(*data++); | 192 | bool sync_done = !iap_getc(*data++); |
181 | 193 | ||
182 | if (abr_status == ABR_STATUS_SYNCING) { | 194 | if (abr_status == ABR_STATUS_SYNCING) |
195 | { | ||
183 | if (sync_done) { | 196 | if (sync_done) { |
184 | abr_status = ABR_STATUS_DONE; | 197 | abr_status = ABR_STATUS_DONE; |
185 | } | 198 | } |