diff options
author | Cástor Muñoz <cmvidal@gmail.com> | 2016-05-12 06:47:38 +0200 |
---|---|---|
committer | Cástor Muñoz <cmvidal@gmail.com> | 2016-05-13 23:21:42 +0200 |
commit | 8fb67f48ab57770c3233352de17846a8a773192a (patch) | |
tree | fcf00f022dcd297c10ab92df8b85021f55e96f6f /firmware/target/arm/s5l8702/ipod6g | |
parent | 2a1e9eb8a8f50f636f86988de1f0cd1b3acf55bb (diff) | |
download | rockbox-8fb67f48ab57770c3233352de17846a8a773192a.tar.gz rockbox-8fb67f48ab57770c3233352de17846a8a773192a.zip |
iPod Classic: updates for uc8702 driver
- Small rework on the UC8702 UART controller to make it compatible with
other s5l870x SOCs. Files moved and renamed, many conditional code
added to deal with capabilities and 'features' of the different CPUs.
- A couple of optimizacions that should not affect the functionality.
Change-Id: I705169f7e8b18d5d1da642f81ffc31c4089780a6
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 | } |