summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/ipod6g
diff options
context:
space:
mode:
authorCástor Muñoz <cmvidal@gmail.com>2016-05-12 06:47:38 +0200
committerCástor Muñoz <cmvidal@gmail.com>2016-05-13 23:21:42 +0200
commit8fb67f48ab57770c3233352de17846a8a773192a (patch)
treefcf00f022dcd297c10ab92df8b85021f55e96f6f /firmware/target/arm/s5l8702/ipod6g
parent2a1e9eb8a8f50f636f86988de1f0cd1b3acf55bb (diff)
downloadrockbox-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.c71
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
43extern struct uartc s5l8702_uart; 48
49extern const struct uartc s5l8702_uartc;
44#ifdef IPOD_ACCESSORY_PROTOCOL 50#ifdef IPOD_ACCESSORY_PROTOCOL
45void iap_rx_isr(int, char*, char*, uint32_t); 51void iap_rx_isr(int, char*, char*, uint32_t);
46#endif 52#endif
47 53
48struct uartc_port ser_port IDATA_ATTR = { 54struct 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 */
71void serial_setup(void) 78void 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
86int tx_rdy(void) 94int 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
99enum { 108static 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
105int abr_status;
106 113
107void serial_bitrate(int rate) 114void 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 }