cmd_bc3450.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  1. /*
  2. * (C) Copyright 2005
  3. * Stefan Strobl, GERSYS GmbH, stefan.strobl@gersys.de
  4. *
  5. * (C) Copyright 2005
  6. * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de.
  7. *
  8. * See file CREDITS for list of people who contributed to this
  9. * project.
  10. *
  11. * This program is free software; you can redistribute it and/or
  12. * modify it under the terms of the GNU General Public License as
  13. * published by the Free Software Foundation; either version 2 of
  14. * the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  24. * MA 02111-1307 USA
  25. */
  26. #include <common.h>
  27. #include <command.h>
  28. /*
  29. * BC3450 specific commands
  30. */
  31. #if (CONFIG_COMMANDS & CFG_CMD_BSP)
  32. #undef DEBUG
  33. #ifdef DEBUG
  34. # define dprintf(fmt,args...) printf(fmt, ##args)
  35. #else
  36. # define dprintf(fmt,args...)
  37. #endif
  38. /*
  39. * Definitions for DS1620 chip
  40. */
  41. #define THERM_START_CONVERT 0xee
  42. #define THERM_RESET 0xaf
  43. #define THERM_READ_CONFIG 0xac
  44. #define THERM_READ_TEMP 0xaa
  45. #define THERM_READ_TL 0xa2
  46. #define THERM_READ_TH 0xa1
  47. #define THERM_WRITE_CONFIG 0x0c
  48. #define THERM_WRITE_TL 0x02
  49. #define THERM_WRITE_TH 0x01
  50. #define CFG_CPU 2
  51. #define CFG_1SHOT 1
  52. #define CFG_STANDALONE 0
  53. struct therm {
  54. int hi;
  55. int lo;
  56. };
  57. /*
  58. * SM501 Register
  59. */
  60. #define SM501_GPIO_CTRL_LOW 0x00000008UL /* gpio pins 0..31 */
  61. #define SM501_GPIO_CTRL_HIGH 0x0000000CUL /* gpio pins 32..63 */
  62. #define SM501_POWER_MODE0_GATE 0x00000040UL
  63. #define SM501_POWER_MODE1_GATE 0x00000048UL
  64. #define POWER_MODE_GATE_GPIO_PWM_I2C 0x00000040UL
  65. #define SM501_GPIO_DATA_LOW 0x00010000UL
  66. #define SM501_GPIO_DATA_HIGH 0x00010004UL
  67. #define SM501_GPIO_DATA_DIR_LOW 0x00010008UL
  68. #define SM501_GPIO_DATA_DIR_HIGH 0x0001000CUL
  69. #define SM501_PANEL_DISPLAY_CONTROL 0x00080000UL
  70. #define SM501_CRT_DISPLAY_CONTROL 0x00080200UL
  71. /* SM501 CRT Display Control Bits */
  72. #define SM501_CDC_SEL (1 << 9)
  73. #define SM501_CDC_TE (1 << 8)
  74. #define SM501_CDC_E (1 << 2)
  75. /* SM501 Panel Display Control Bits */
  76. #define SM501_PDC_FPEN (1 << 27)
  77. #define SM501_PDC_BIAS (1 << 26)
  78. #define SM501_PDC_DATA (1 << 25)
  79. #define SM501_PDC_VDDEN (1 << 24)
  80. /* SM501 GPIO Data LOW Bits */
  81. #define SM501_GPIO24 0x01000000
  82. #define SM501_GPIO25 0x02000000
  83. #define SM501_GPIO26 0x04000000
  84. #define SM501_GPIO27 0x08000000
  85. #define SM501_GPIO28 0x10000000
  86. #define SM501_GPIO29 0x20000000
  87. #define SM501_GPIO30 0x40000000
  88. #define SM501_GPIO31 0x80000000
  89. /* SM501 GPIO Data HIGH Bits */
  90. #define SM501_GPIO46 0x00004000
  91. #define SM501_GPIO47 0x00008000
  92. #define SM501_GPIO48 0x00010000
  93. #define SM501_GPIO49 0x00020000
  94. #define SM501_GPIO50 0x00040000
  95. #define SM501_GPIO51 0x00080000
  96. /* BC3450 GPIOs @ SM501 Data LOW */
  97. #define DIP (SM501_GPIO24 | SM501_GPIO25 | SM501_GPIO26 | SM501_GPIO27)
  98. #define DS1620_DQ SM501_GPIO29 /* I/O */
  99. #define DS1620_CLK SM501_GPIO30 /* High active O/P */
  100. #define DS1620_RES SM501_GPIO31 /* Low active O/P */
  101. /* BC3450 GPIOs @ SM501 Data HIGH */
  102. #define BUZZER SM501_GPIO47 /* Low active O/P */
  103. #define DS1620_TLOW SM501_GPIO48 /* High active I/P */
  104. #define PWR_OFF SM501_GPIO49 /* Low active O/P */
  105. #define FP_DATA_TRI SM501_GPIO50 /* High active O/P */
  106. /*
  107. * Initialise GPIO on SM501
  108. *
  109. * This function may be called from several other functions.
  110. * Yet, the initialisation sequence is executed only the first
  111. * time the function is called.
  112. */
  113. int sm501_gpio_init(void)
  114. {
  115. static int init_done = 0;
  116. if(init_done) {
  117. /* dprintf("sm501_gpio_init: nothing to be done.\n"); */
  118. return 1;
  119. }
  120. /* enable SM501 GPIO control (in both power modes) */
  121. *(vu_long *) (SM501_MMIO_BASE + SM501_POWER_MODE0_GATE) |= POWER_MODE_GATE_GPIO_PWM_I2C;
  122. *(vu_long *) (SM501_MMIO_BASE + SM501_POWER_MODE1_GATE) |= POWER_MODE_GATE_GPIO_PWM_I2C;
  123. /* set up default O/Ps */
  124. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &= ~(DS1620_RES | DS1620_CLK);
  125. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |= DS1620_DQ;
  126. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) &= ~(FP_DATA_TRI);
  127. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) |= (BUZZER | PWR_OFF);
  128. /* configure directions for SM501 GPIO pins */
  129. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_CTRL_LOW) &= ~(0xFF << 24);
  130. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_CTRL_HIGH) &= ~(0x3F << 14);
  131. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) &= ~(DIP | DS1620_DQ);
  132. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) |= (DS1620_RES | DS1620_CLK);
  133. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_HIGH) &= ~DS1620_TLOW;
  134. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_HIGH) |= (PWR_OFF | BUZZER | FP_DATA_TRI);
  135. init_done = 1;
  136. /* dprintf("sm501_gpio_init: done.\n"); */
  137. return 0;
  138. }
  139. /*
  140. * dip - read Config Inputs
  141. *
  142. * read and prints the dip switch
  143. * and/or external config inputs (4bits) 0...0x0F
  144. */
  145. int cmd_dip (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  146. {
  147. vu_long rc = 0;
  148. sm501_gpio_init();
  149. /* read dip switch */
  150. rc = *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW);
  151. rc = ~rc;
  152. rc &= DIP;
  153. rc = (int)(rc >> 24);
  154. /* plausibility check */
  155. if (rc > 0x0F)
  156. return -1;
  157. printf ("0x%x\n", rc);
  158. return 0;
  159. }
  160. U_BOOT_CMD(
  161. dip , 1, 1, cmd_dip,
  162. "dip - read dip switch and config inputs\n",
  163. "\n"
  164. " - prints the state of the dip switch and/or\n"
  165. " external configuration inputs as hex value.\n"
  166. " - \"Config 1\" is the LSB\n"
  167. );
  168. /*
  169. * buz - turns Buzzer on/off
  170. */
  171. #ifdef CONFIG_BC3450_BUZZER
  172. static int cmd_buz (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  173. {
  174. if (argc != 2) {
  175. printf ("Usage:\nspecify one argument: \"on\" or \"off\"\n");
  176. return 1;
  177. }
  178. sm501_gpio_init();
  179. if (strncmp (argv[1], "on", 2) == 0) {
  180. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) &= ~(BUZZER);
  181. return 0;
  182. }
  183. else if (strncmp (argv[1], "off", 3) == 0) {
  184. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) |= BUZZER;
  185. return 0;
  186. }
  187. printf ("Usage:\nspecify one argument: \"on\" or \"off\"\n");
  188. return 1;
  189. }
  190. U_BOOT_CMD(
  191. buz , 2, 1, cmd_buz,
  192. "buz - turns buzzer on/off\n",
  193. "\n"
  194. "buz <on/off>\n"
  195. " - turns the buzzer on or off\n"
  196. );
  197. #endif /* CONFIG_BC3450_BUZZER */
  198. /*
  199. * fp - front panel commands
  200. */
  201. static int cmd_fp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  202. {
  203. sm501_gpio_init();
  204. if (strncmp (argv[1], "on", 2) == 0) {
  205. /* turn on VDD first */
  206. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_VDDEN;
  207. udelay(1000);
  208. /* then put data on */
  209. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_DATA;
  210. /* wait some time and enable backlight */
  211. udelay(1000);
  212. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_BIAS;
  213. udelay(1000);
  214. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_FPEN;
  215. return 0;
  216. }
  217. else if (strncmp (argv[1], "off", 3) == 0) {
  218. /* turn off the backlight first */
  219. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_FPEN;
  220. udelay(1000);
  221. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_BIAS;
  222. udelay(200000);
  223. /* wait some time, then remove data */
  224. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_DATA;
  225. udelay(1000);
  226. /* and remove VDD last */
  227. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_VDDEN;
  228. return 0;
  229. }
  230. else if (strncmp (argv[1], "bl", 2) == 0) {
  231. /* turn on/off backlight only */
  232. if (strncmp (argv[2], "on", 2) == 0) {
  233. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_BIAS;
  234. udelay(1000);
  235. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) |= SM501_PDC_FPEN;
  236. return 0;
  237. }
  238. else if (strncmp (argv[2], "off", 3) == 0) {
  239. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_FPEN;
  240. udelay(1000);
  241. *(vu_long *)(SM501_MMIO_BASE + SM501_PANEL_DISPLAY_CONTROL) &= ~SM501_PDC_BIAS;
  242. return 0;
  243. }
  244. }
  245. #ifdef CONFIG_BC3450_CRT
  246. else if (strncmp (argv[1], "crt", 3) == 0) {
  247. /* enables/disables the crt output (debug only) */
  248. if(strncmp (argv[2], "on", 2) == 0) {
  249. *(vu_long *)(SM501_MMIO_BASE + SM501_CRT_DISPLAY_CONTROL) |=
  250. (SM501_CDC_TE | SM501_CDC_E);
  251. *(vu_long *)(SM501_MMIO_BASE + SM501_CRT_DISPLAY_CONTROL) &=
  252. ~SM501_CDC_SEL;
  253. return 0;
  254. }
  255. else if (strncmp (argv[2], "off", 3) == 0) {
  256. *(vu_long *)(SM501_MMIO_BASE + SM501_CRT_DISPLAY_CONTROL) &=
  257. ~(SM501_CDC_TE | SM501_CDC_E);
  258. *(vu_long *)(SM501_MMIO_BASE + SM501_CRT_DISPLAY_CONTROL) |=
  259. SM501_CDC_SEL;
  260. return 0;
  261. }
  262. }
  263. #endif /* CONFIG_BC3450_CRT */
  264. printf("Usage:%s\n", cmdtp->help);
  265. return 1;
  266. }
  267. U_BOOT_CMD(
  268. fp , 3, 1, cmd_fp,
  269. "fp - front panes access functions\n",
  270. "\n"
  271. "fp bl <on/off>\n"
  272. " - turns the CCFL backlight of the display on/off\n"
  273. "fp <on/off>\n"
  274. " - turns the whole display on/off\n"
  275. #ifdef CONFIG_BC3450_CRT
  276. "fp crt <on/off>\n"
  277. " - enables/disables the crt output (debug only)\n"
  278. #endif /* CONFIG_BC3450_CRT */
  279. );
  280. /*
  281. * temp - DS1620 thermometer
  282. */
  283. /* GERSYS BC3450 specific functions */
  284. static inline void bc_ds1620_set_clk(int clk)
  285. {
  286. if(clk)
  287. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |= DS1620_CLK;
  288. else
  289. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &= ~DS1620_CLK;
  290. }
  291. static inline void bc_ds1620_set_data(int dat)
  292. {
  293. if(dat)
  294. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |= DS1620_DQ;
  295. else
  296. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &= ~DS1620_DQ;
  297. }
  298. static inline int bc_ds1620_get_data(void)
  299. {
  300. vu_long rc;
  301. rc = *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW);
  302. rc &= DS1620_DQ;
  303. if(rc != 0)
  304. rc = 1;
  305. return (int)rc;
  306. }
  307. static inline void bc_ds1620_set_data_dir(int dir)
  308. {
  309. if(dir) /* in */
  310. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) &= ~DS1620_DQ;
  311. else /* out */
  312. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_DIR_LOW) |= DS1620_DQ;
  313. }
  314. static inline void bc_ds1620_set_reset(int res)
  315. {
  316. if(res)
  317. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) |= DS1620_RES;
  318. else
  319. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_LOW) &= ~DS1620_RES;
  320. }
  321. /* hardware independent functions */
  322. static void ds1620_send_bits(int nr, int value)
  323. {
  324. int i;
  325. for (i = 0; i < nr; i++) {
  326. bc_ds1620_set_data(value & 1);
  327. bc_ds1620_set_clk(0);
  328. udelay(1);
  329. bc_ds1620_set_clk(1);
  330. udelay(1);
  331. value >>= 1;
  332. }
  333. }
  334. static unsigned int ds1620_recv_bits(int nr)
  335. {
  336. unsigned int value = 0, mask = 1;
  337. int i;
  338. bc_ds1620_set_data(0);
  339. for (i = 0; i < nr; i++) {
  340. bc_ds1620_set_clk(0);
  341. udelay(1);
  342. if (bc_ds1620_get_data())
  343. value |= mask;
  344. mask <<= 1;
  345. bc_ds1620_set_clk(1);
  346. udelay(1);
  347. }
  348. return value;
  349. }
  350. static void ds1620_out(int cmd, int bits, int value)
  351. {
  352. bc_ds1620_set_clk(1);
  353. bc_ds1620_set_data_dir(0);
  354. bc_ds1620_set_reset(0);
  355. udelay(1);
  356. bc_ds1620_set_reset(1);
  357. udelay(1);
  358. ds1620_send_bits(8, cmd);
  359. if (bits)
  360. ds1620_send_bits(bits, value);
  361. udelay(1);
  362. /* go stand alone */
  363. bc_ds1620_set_data_dir(1);
  364. bc_ds1620_set_reset(0);
  365. bc_ds1620_set_clk(0);
  366. udelay(10000);
  367. }
  368. static unsigned int ds1620_in(int cmd, int bits)
  369. {
  370. unsigned int value;
  371. bc_ds1620_set_clk(1);
  372. bc_ds1620_set_data_dir(0);
  373. bc_ds1620_set_reset(0);
  374. udelay(1);
  375. bc_ds1620_set_reset(1);
  376. udelay(1);
  377. ds1620_send_bits(8, cmd);
  378. bc_ds1620_set_data_dir(1);
  379. value = ds1620_recv_bits(bits);
  380. /* go stand alone */
  381. bc_ds1620_set_data_dir(1);
  382. bc_ds1620_set_reset(0);
  383. bc_ds1620_set_clk(0);
  384. return value;
  385. }
  386. static int cvt_9_to_int(unsigned int val)
  387. {
  388. if (val & 0x100)
  389. val |= 0xfffffe00;
  390. return val;
  391. }
  392. /* set thermostate thresholds */
  393. static void ds1620_write_state(struct therm *therm)
  394. {
  395. ds1620_out(THERM_WRITE_TL, 9, therm->lo);
  396. ds1620_out(THERM_WRITE_TH, 9, therm->hi);
  397. ds1620_out(THERM_START_CONVERT, 0, 0);
  398. }
  399. static int cmd_temp (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  400. {
  401. int i;
  402. struct therm therm;
  403. sm501_gpio_init();
  404. /* print temperature */
  405. if (argc == 1) {
  406. i = cvt_9_to_int(ds1620_in(THERM_READ_TEMP, 9));
  407. printf("%d.%d C\n", i >> 1, i & 1 ? 5 : 0);
  408. return 0;
  409. }
  410. /* set to default operation */
  411. if (strncmp (argv[1], "set", 3) == 0) {
  412. if(strncmp (argv[2], "default", 3) == 0) {
  413. therm.hi = +88;
  414. therm.lo = -20;
  415. therm.hi <<= 1;
  416. therm.lo <<= 1;
  417. ds1620_write_state(&therm);
  418. ds1620_out(THERM_WRITE_CONFIG, 8, CFG_STANDALONE);
  419. return 0;
  420. }
  421. }
  422. printf ("Usage:%s\n", cmdtp->help);
  423. return 1;
  424. }
  425. U_BOOT_CMD(
  426. temp , 3, 1, cmd_temp,
  427. "temp - print current temperature\n",
  428. "\n"
  429. "temp\n"
  430. " - print current temperature\n"
  431. );
  432. #ifdef CONFIG_BC3450_CAN
  433. /*
  434. * Initialise CAN interface
  435. *
  436. * return 1 on CAN initialization failure
  437. * return 0 if no failure
  438. */
  439. int can_init(void)
  440. {
  441. static int init_done = 0;
  442. int i;
  443. struct mpc5xxx_mscan *can1 =
  444. (struct mpc5xxx_mscan *)(CFG_MBAR + 0x0900);
  445. struct mpc5xxx_mscan *can2 =
  446. (struct mpc5xxx_mscan *)(CFG_MBAR + 0x0980);
  447. /* GPIO configuration of the CAN pins is done in BC3450.h */
  448. if (!init_done) {
  449. /* init CAN 1 */
  450. can1->canctl1 |= 0x80; /* CAN enable */
  451. udelay(100);
  452. i = 0;
  453. can1->canctl0 |= 0x02; /* sleep mode */
  454. /* wait until sleep mode reached */
  455. while (!(can1->canctl1 & 0x02)) {
  456. udelay(10);
  457. i++;
  458. if (i == 10) {
  459. printf ("%s: CAN1 initialize error, "
  460. "can not enter sleep mode!\n",
  461. __FUNCTION__);
  462. return 1;
  463. }
  464. }
  465. i = 0;
  466. can1->canctl0 = 0x01; /* enter init mode */
  467. /* wait until init mode reached */
  468. while (!(can1->canctl1 & 0x01)) {
  469. udelay(10);
  470. i++;
  471. if (i == 10) {
  472. printf ("%s: CAN1 initialize error, "
  473. "can not enter init mode!\n",
  474. __FUNCTION__);
  475. return 1;
  476. }
  477. }
  478. can1->canctl1 = 0x80;
  479. can1->canctl1 |= 0x40;
  480. can1->canbtr0 = 0x0F;
  481. can1->canbtr1 = 0x7F;
  482. can1->canidac &= ~(0x30);
  483. can1->canidar1 = 0x00;
  484. can1->canidar3 = 0x00;
  485. can1->canidar5 = 0x00;
  486. can1->canidar7 = 0x00;
  487. can1->canidmr0 = 0xFF;
  488. can1->canidmr1 = 0xFF;
  489. can1->canidmr2 = 0xFF;
  490. can1->canidmr3 = 0xFF;
  491. can1->canidmr4 = 0xFF;
  492. can1->canidmr5 = 0xFF;
  493. can1->canidmr6 = 0xFF;
  494. can1->canidmr7 = 0xFF;
  495. i = 0;
  496. can1->canctl0 &= ~(0x01); /* leave init mode */
  497. can1->canctl0 &= ~(0x02);
  498. /* wait until init and sleep mode left */
  499. while ((can1->canctl1 & 0x01) || (can1->canctl1 & 0x02)) {
  500. udelay(10);
  501. i++;
  502. if (i == 10) {
  503. printf ("%s: CAN1 initialize error, "
  504. "can not leave init/sleep mode!\n",
  505. __FUNCTION__);
  506. return 1;
  507. }
  508. }
  509. /* init CAN 2 */
  510. can2->canctl1 |= 0x80; /* CAN enable */
  511. udelay(100);
  512. i = 0;
  513. can2->canctl0 |= 0x02; /* sleep mode */
  514. /* wait until sleep mode reached */
  515. while (!(can2->canctl1 & 0x02)) {
  516. udelay(10);
  517. i++;
  518. if (i == 10) {
  519. printf ("%s: CAN2 initialize error, "
  520. "can not enter sleep mode!\n",
  521. __FUNCTION__);
  522. return 1;
  523. }
  524. }
  525. i = 0;
  526. can2->canctl0 = 0x01; /* enter init mode */
  527. /* wait until init mode reached */
  528. while (!(can2->canctl1 & 0x01)) {
  529. udelay(10);
  530. i++;
  531. if (i == 10) {
  532. printf ("%s: CAN2 initialize error, "
  533. "can not enter init mode!\n",
  534. __FUNCTION__);
  535. return 1;
  536. }
  537. }
  538. can2->canctl1 = 0x80;
  539. can2->canctl1 |= 0x40;
  540. can2->canbtr0 = 0x0F;
  541. can2->canbtr1 = 0x7F;
  542. can2->canidac &= ~(0x30);
  543. can2->canidar1 = 0x00;
  544. can2->canidar3 = 0x00;
  545. can2->canidar5 = 0x00;
  546. can2->canidar7 = 0x00;
  547. can2->canidmr0 = 0xFF;
  548. can2->canidmr1 = 0xFF;
  549. can2->canidmr2 = 0xFF;
  550. can2->canidmr3 = 0xFF;
  551. can2->canidmr4 = 0xFF;
  552. can2->canidmr5 = 0xFF;
  553. can2->canidmr6 = 0xFF;
  554. can2->canidmr7 = 0xFF;
  555. can2->canctl0 &= ~(0x01); /* leave init mode */
  556. can2->canctl0 &= ~(0x02);
  557. i = 0;
  558. /* wait until init mode left */
  559. while ((can2->canctl1 & 0x01) || (can2->canctl1 & 0x02)) {
  560. udelay(10);
  561. i++;
  562. if (i == 10) {
  563. printf ("%s: CAN2 initialize error, "
  564. "can not leave init/sleep mode!\n",
  565. __FUNCTION__);
  566. return 1;
  567. }
  568. }
  569. init_done = 1;
  570. }
  571. return 0;
  572. }
  573. /*
  574. * Do CAN test
  575. * by sending message between CAN1 and CAN2
  576. *
  577. * return 1 on CAN failure
  578. * return 0 if no failure
  579. */
  580. int do_can(char *argv[])
  581. {
  582. int i;
  583. struct mpc5xxx_mscan *can1 =
  584. (struct mpc5xxx_mscan *)(CFG_MBAR + 0x0900);
  585. struct mpc5xxx_mscan *can2 =
  586. (struct mpc5xxx_mscan *)(CFG_MBAR + 0x0980);
  587. /* send a message on CAN1 */
  588. can1->cantbsel = 0x01;
  589. can1->cantxfg.idr[0] = 0x55;
  590. can1->cantxfg.idr[1] = 0x00;
  591. can1->cantxfg.idr[1] &= ~0x8;
  592. can1->cantxfg.idr[1] &= ~0x10;
  593. can1->cantxfg.dsr[0] = 0xCC;
  594. can1->cantxfg.dlr = 1;
  595. can1->cantxfg.tbpr = 0;
  596. can1->cantflg = 0x01;
  597. i = 0;
  598. while ((can1->cantflg & 0x01) == 0) {
  599. i++;
  600. if (i == 10) {
  601. printf ("%s: CAN1 send timeout, "
  602. "can not send message!\n",
  603. __FUNCTION__);
  604. return 1;
  605. }
  606. udelay(1000);
  607. }
  608. udelay(1000);
  609. i = 0;
  610. while (!(can2->canrflg & 0x01)) {
  611. i++;
  612. if (i == 10) {
  613. printf ("%s: CAN2 receive timeout, "
  614. "no message received!\n",
  615. __FUNCTION__);
  616. return 1;
  617. }
  618. udelay(1000);
  619. }
  620. if (can2->canrxfg.dsr[0] != 0xCC) {
  621. printf ("%s: CAN2 receive error, "
  622. "data mismatch!\n",
  623. __FUNCTION__);
  624. return 1;
  625. }
  626. /* send a message on CAN2 */
  627. can2->cantbsel = 0x01;
  628. can2->cantxfg.idr[0] = 0x55;
  629. can2->cantxfg.idr[1] = 0x00;
  630. can2->cantxfg.idr[1] &= ~0x8;
  631. can2->cantxfg.idr[1] &= ~0x10;
  632. can2->cantxfg.dsr[0] = 0xCC;
  633. can2->cantxfg.dlr = 1;
  634. can2->cantxfg.tbpr = 0;
  635. can2->cantflg = 0x01;
  636. i = 0;
  637. while ((can2->cantflg & 0x01) == 0) {
  638. i++;
  639. if (i == 10) {
  640. printf ("%s: CAN2 send error, "
  641. "can not send message!\n",
  642. __FUNCTION__);
  643. return 1;
  644. }
  645. udelay(1000);
  646. }
  647. udelay(1000);
  648. i = 0;
  649. while (!(can1->canrflg & 0x01)) {
  650. i++;
  651. if (i == 10) {
  652. printf ("%s: CAN1 receive timeout, "
  653. "no message received!\n",
  654. __FUNCTION__);
  655. return 1;
  656. }
  657. udelay(1000);
  658. }
  659. if (can1->canrxfg.dsr[0] != 0xCC) {
  660. printf ("%s: CAN1 receive error 0x%02x\n",
  661. __FUNCTION__, (can1->canrxfg.dsr[0]));
  662. return 1;
  663. }
  664. return 0;
  665. }
  666. #endif /* CONFIG_BC3450_CAN */
  667. /*
  668. * test - BC3450 HW test routines
  669. */
  670. int cmd_test(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
  671. {
  672. #ifdef CONFIG_BC3450_CAN
  673. int rcode;
  674. can_init();
  675. #endif /* CONFIG_BC3450_CAN */
  676. sm501_gpio_init();
  677. if (argc != 2) {
  678. printf ("Usage:%s\n", cmdtp->help);
  679. return 1;
  680. }
  681. if (strncmp (argv[1], "unit-off", 8) == 0) {
  682. printf ("waiting 2 seconds...\n");
  683. udelay(2000000);
  684. *(vu_long *) (SM501_MMIO_BASE + SM501_GPIO_DATA_HIGH) &= ~PWR_OFF;
  685. return 0;
  686. }
  687. #ifdef CONFIG_BC3450_CAN
  688. else if (strncmp (argv[1], "can", 2) == 0) {
  689. rcode = do_can (argv);
  690. if (simple_strtoul(argv[2], NULL, 10) == 2) {
  691. if (rcode == 0)
  692. printf ("OK\n");
  693. else
  694. printf ("Error\n");
  695. }
  696. return rcode;
  697. }
  698. #endif /* CONFIG_BC3450_CAN */
  699. printf ("Usage:%s\n", cmdtp->help);
  700. return 1;
  701. }
  702. U_BOOT_CMD(
  703. test , 2, 1, cmd_test,
  704. "test - unit test routines\n",
  705. "\n"
  706. #ifdef CONFIG_BC3450_CAN
  707. "test can\n"
  708. " - connect CAN1 (X8) with CAN2 (X9) for this test\n"
  709. #endif /* CONFIG_BC3450_CAN */
  710. "test unit-off\n"
  711. " - turns off the BC3450 unit\n"
  712. " WARNING: Unsaved environment variables will be lost!\n"
  713. );
  714. #endif /* CFG_CMD_BSP */