summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8702/ipod6g
diff options
context:
space:
mode:
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 }