gpio_nutos.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*!
  2. * Copyright (C) 2001-2010 by egnite Software GmbH
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*!
  35. * $Id: gpio.c,v 1.4 2009/01/18 16:45:28 haraldkipp Exp $
  36. */
  37. #include <arch/avr32.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <dev/gpio.h>
  41. #include <avr32/io.h>
  42. /*
  43. * Convert the external bank to the AVR32 representation.
  44. */
  45. static int get_avr32_bank(int bank)
  46. {
  47. int avr32_bank = 0;
  48. switch (bank) {
  49. default:
  50. case NUTGPIO_PORT:
  51. case NUTGPIO_PORTA:
  52. avr32_bank = 0;
  53. break;
  54. case NUTGPIO_PORTB:
  55. avr32_bank = 1;
  56. break;
  57. case NUTGPIO_PORTC:
  58. avr32_bank = 2;
  59. break;
  60. case NUTGPIO_PORTD:
  61. avr32_bank = 3;
  62. break;
  63. case NUTGPIO_PORTE:
  64. avr32_bank = 4;
  65. break;
  66. case NUTGPIO_PORTF:
  67. avr32_bank = 5;
  68. break;
  69. case NUTGPIO_PORTG:
  70. avr32_bank = 6;
  71. break;
  72. case NUTGPIO_PORTH:
  73. avr32_bank = 7;
  74. break;
  75. case NUTGPIO_PORTI:
  76. avr32_bank = 8;
  77. break;
  78. case NUTGPIO_PORTJ:
  79. avr32_bank = 9;
  80. break;
  81. case NUTGPIO_PORTK:
  82. avr32_bank = 10;
  83. break;
  84. case NUTGPIO_PORTL:
  85. avr32_bank = 11;
  86. break;
  87. }
  88. if (avr32_bank >= AVR32_GPIO_PORT_LENGTH) {
  89. avr32_bank = AVR32_GPIO_PORT_LENGTH - 1;
  90. }
  91. return (avr32_bank);
  92. }
  93. /*!
  94. \internal
  95. Switch GPIO Peripheral Mux to specified \a function where function is one
  96. of the GPIO_CFG_PERIPHERALx values.
  97. Note that GPIO_CFG_PERIPHERALx values are mutually exclusive.
  98. */
  99. static int enable_module_pin(int avr32_bank, int mask, unsigned int function)
  100. {
  101. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  102. // Enable the correct function.
  103. switch (function) {
  104. case GPIO_CFG_PERIPHERAL0: // A function.
  105. gpio_port->pmr0c = mask;
  106. gpio_port->pmr1c = mask;
  107. #ifdef AVR32_GPIO_PMR2C
  108. gpio_port->pmr2c = mask;
  109. #endif
  110. break;
  111. case GPIO_CFG_PERIPHERAL1: // B function.
  112. gpio_port->pmr0s = mask;
  113. gpio_port->pmr1c = mask;
  114. #ifdef AVR32_GPIO_PMR2C
  115. gpio_port->pmr2c = mask;
  116. #endif
  117. break;
  118. case GPIO_CFG_PERIPHERAL2: // C function.
  119. gpio_port->pmr0c = mask;
  120. gpio_port->pmr1s = mask;
  121. #ifdef AVR32_GPIO_PMR2C
  122. gpio_port->pmr2c = mask;
  123. #endif
  124. break;
  125. default:
  126. return -1;
  127. }
  128. // Disable GPIO control.
  129. gpio_port->gperc = mask;
  130. return 0;
  131. }
  132. /*!
  133. \internal
  134. Switch GPIO Peripheral Mux to specified \a function where function is one
  135. of the AVR32 compiler header values.
  136. This function is intended to be used by drivers
  137. */
  138. void gpio_enable_module_pin(unsigned int pin, unsigned int function)
  139. {
  140. unsigned int peripheral = 0;
  141. switch ( function )
  142. {
  143. case 0: peripheral = GPIO_CFG_PERIPHERAL0; break;
  144. case 1: peripheral = GPIO_CFG_PERIPHERAL1; break;
  145. case 2: peripheral = GPIO_CFG_PERIPHERAL2; break;
  146. default:
  147. while(1); // Unrecognized peripheral choice
  148. break;
  149. }
  150. enable_module_pin(pin >> 5, _BV(pin & 0x1F), peripheral);
  151. }
  152. int avr32_enable_module_pin(unsigned int pin, unsigned int function)
  153. {
  154. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[pin >> 5];
  155. // Enable the correct function.
  156. switch (function)
  157. {
  158. case 0: // A function.
  159. gpio_port->pmr0c = 1 << (pin & 0x1F);
  160. gpio_port->pmr1c = 1 << (pin & 0x1F);
  161. #ifdef AVR32_GPIO_PMR2C
  162. gpio_port->pmr2c = 1 << (pin & 0x1F);
  163. #endif
  164. break;
  165. case 1: // B function.
  166. gpio_port->pmr0s = 1 << (pin & 0x1F);
  167. gpio_port->pmr1c = 1 << (pin & 0x1F);
  168. #ifdef AVR32_GPIO_PMR2C
  169. gpio_port->pmr2c = 1 << (pin & 0x1F);
  170. #endif
  171. break;
  172. case 2: // C function.
  173. gpio_port->pmr0c = 1 << (pin & 0x1F);
  174. gpio_port->pmr1s = 1 << (pin & 0x1F);
  175. #ifdef AVR32_GPIO_PMR2C
  176. gpio_port->pmr2c = 1 << (pin & 0x1F);
  177. #endif
  178. break;
  179. case 3: // D function.
  180. gpio_port->pmr0s = 1 << (pin & 0x1F);
  181. gpio_port->pmr1s = 1 << (pin & 0x1F);
  182. #ifdef AVR32_GPIO_PMR2C
  183. gpio_port->pmr2c = 1 << (pin & 0x1F);
  184. #endif
  185. break;
  186. #ifdef AVR32_GPIO_PMR2C
  187. case 4: // E function.
  188. gpio_port->pmr0c = 1 << (pin & 0x1F);
  189. gpio_port->pmr1c = 1 << (pin & 0x1F);
  190. gpio_port->pmr2s = 1 << (pin & 0x1F);
  191. break;
  192. case 5: // F function.
  193. gpio_port->pmr0s = 1 << (pin & 0x1F);
  194. gpio_port->pmr1c = 1 << (pin & 0x1F);
  195. gpio_port->pmr2s = 1 << (pin & 0x1F);
  196. break;
  197. case 6: // G function.
  198. gpio_port->pmr0c = 1 << (pin & 0x1F);
  199. gpio_port->pmr1s = 1 << (pin & 0x1F);
  200. gpio_port->pmr2s = 1 << (pin & 0x1F);
  201. break;
  202. case 7: // H function.
  203. gpio_port->pmr0s = 1 << (pin & 0x1F);
  204. gpio_port->pmr1s = 1 << (pin & 0x1F);
  205. gpio_port->pmr2s = 1 << (pin & 0x1F);
  206. break;
  207. #endif
  208. default:
  209. return -1;
  210. }
  211. // Disable GPIO control.
  212. gpio_port->gperc = 1 << (pin & 0x1F);
  213. return 0;
  214. }
  215. /*!
  216. * \brief Get pin level.
  217. *
  218. * \param bank GPIO bank/port number.
  219. * \param bit Bit number of the specified bank/port.
  220. *
  221. * \return 1 if the pin level is high. 0 is returned if the pin level
  222. * is low or if the pin is undefined.
  223. */
  224. int GpioPinGet(int bank, int bit)
  225. {
  226. int avr32_bank = get_avr32_bank(bank);
  227. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  228. return (gpio_port->pvr >> (bit & 0x1F)) & 1;
  229. }
  230. /*!
  231. * \brief Set pin level to low.
  232. *
  233. * Trying to set undefined pins is silently ignored.
  234. *
  235. * \param bank GPIO bank/port number.
  236. * \param bit Bit number of the specified bank/port.
  237. */
  238. void GpioPinSetLow(int bank, int bit)
  239. {
  240. int avr32_bank = get_avr32_bank(bank);
  241. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  242. gpio_port->ovrc = 1 << (bit & 0x1F); // Value to be driven on the I/O line: 0.
  243. }
  244. /*!
  245. * \brief Set pin level to high.
  246. *
  247. * Trying to set undefined pins is silently ignored.
  248. *
  249. * \param bank GPIO bank/port number.
  250. * \param bit Bit number of the specified bank/port.
  251. */
  252. void GpioPinSetHigh(int bank, int bit)
  253. {
  254. int avr32_bank = get_avr32_bank(bank);
  255. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  256. gpio_port->ovrs = 1 << (bit & 0x1F); // Value to be driven on the I/O line: 1.
  257. }
  258. /*!
  259. * \brief Set pin level.
  260. *
  261. * Trying to set undefined pins is silently ignored.
  262. *
  263. * \param bank GPIO bank/port number.
  264. * \param bit Bit number of the specified bank/port.
  265. * \param value Level, 0 for low or any other value for high.
  266. */
  267. void GpioPinSet(int bank, int bit, int value)
  268. {
  269. int avr32_bank = get_avr32_bank(bank);
  270. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  271. if (value) {
  272. gpio_port->ovrs = 1 << (bit & 0x1F); // Value to be driven on the I/O line: 1.
  273. } else {
  274. gpio_port->ovrc = 1 << (bit & 0x1F); // Value to be driven on the I/O line: 0.
  275. }
  276. }
  277. /*!
  278. * \brief Get all pin levels of a specified bank/port.
  279. *
  280. * \param bank GPIO bank/port number.
  281. *
  282. * \return Pin levels. 0 is returned for unknown banks and pins.
  283. */
  284. unsigned int GpioPortGet(int bank)
  285. {
  286. int avr32_bank = get_avr32_bank(bank);
  287. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  288. return gpio_port->pvr;
  289. }
  290. /*!
  291. * \brief Set multiple pin levels of a bank/port to low.
  292. *
  293. * \param bank GPIO bank/port number.
  294. * \param mask Pin levels are set to low, if the corresponding
  295. * bit in this mask is 1.
  296. *
  297. * \return Levels.
  298. */
  299. void GpioPortSetLow(int bank, unsigned int mask)
  300. {
  301. int avr32_bank = get_avr32_bank(bank);
  302. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  303. gpio_port->ovrc = mask; // Value to be driven on the I/O line: 0.
  304. }
  305. /*!
  306. * \brief Set multiple pin levels of a bank/port to high.
  307. *
  308. * Trying to set undefined ports is silently ignored.
  309. *
  310. * \param bank GPIO bank/port number.
  311. * \param mask Pin levels are set to high, if the corresponding
  312. * bit in this mask is 1.
  313. */
  314. void GpioPortSetHigh(int bank, unsigned int mask)
  315. {
  316. int avr32_bank = get_avr32_bank(bank);
  317. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  318. gpio_port->ovrs = mask; // Value to be driven on the I/O line: 1.
  319. }
  320. /*!
  321. * \brief Set all pin levels of a bank/port.
  322. *
  323. * This routine can be used to simultaneously set all pins of a specific
  324. * port. However, in some implementations the high bit values will be
  325. * set before the low bit values. If this is a problem, you should use
  326. * GpioPortSetHigh() and GpioPortSetLow().
  327. *
  328. * \param bank GPIO bank/port number.
  329. * \param value Pin levels are set to high, if the corresponding
  330. * bit in this mask is 1. All other pin levels are
  331. * set to low.
  332. */
  333. void GpioPortSet(int bank, unsigned int value)
  334. {
  335. int avr32_bank = get_avr32_bank(bank);
  336. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  337. gpio_port->ovr = value;
  338. }
  339. /*!
  340. * \brief Get pin configuration.
  341. *
  342. * \param bank GPIO bank/port number.
  343. * \param bit Bit number of the specified bank/port.
  344. *
  345. * \return Attribute flags of the pin.
  346. */
  347. uint32_t GpioPinConfigGet(int bank, int bit)
  348. {
  349. uint32_t rc = 0;
  350. uint8_t is_gpio = 0;
  351. int avr32_bank = get_avr32_bank(bank);
  352. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  353. if ((gpio_port->gper & _BV(bit)) == 0) {
  354. rc |= GPIO_CFG_DISABLED;
  355. } else {
  356. is_gpio = 1;
  357. }
  358. if (gpio_port->oder & _BV(bit)) {
  359. rc |= GPIO_CFG_OUTPUT;
  360. }
  361. if (gpio_port->gfer & _BV(bit)) {
  362. rc |= GPIO_CFG_DEBOUNCE;
  363. }
  364. if (gpio_port->puer & _BV(bit)) {
  365. rc |= GPIO_CFG_PULLUP;
  366. }
  367. if (is_gpio == 0) {
  368. if (gpio_port->pmr1 & _BV(bit)) {
  369. if (gpio_port->pmr0 & _BV(bit)) {
  370. rc |= GPIO_CFG_PERIPHERAL3;
  371. } else {
  372. rc |= GPIO_CFG_PERIPHERAL2;
  373. }
  374. } else {
  375. if (gpio_port->pmr0 & _BV(bit)) {
  376. rc |= GPIO_CFG_PERIPHERAL1;
  377. } else {
  378. rc |= GPIO_CFG_PERIPHERAL0;
  379. }
  380. }
  381. }
  382. return rc;
  383. }
  384. /*!
  385. * \brief Set port wide pin configuration.
  386. *
  387. * \note This function does not check for undefined ports and pins or
  388. * invalid attributes. If this is required, use GpioPinConfigSet().
  389. *
  390. * \param bank GPIO bank/port number.
  391. * \param mask The given attributes are set for a specific pin, if the
  392. * corresponding bit in this mask is 1.
  393. * \param flags Attribute flags to set.
  394. *
  395. * \return Always 0.
  396. */
  397. int GpioPortConfigSet(int bank, unsigned int mask, uint32_t flags)
  398. {
  399. #define PERIPHERALS_MASK (GPIO_CFG_PERIPHERAL0|GPIO_CFG_PERIPHERAL1|GPIO_CFG_PERIPHERAL2|GPIO_CFG_PERIPHERAL3)
  400. int avr32_bank = get_avr32_bank(bank);
  401. volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
  402. if (flags & GPIO_CFG_PULLUP) {
  403. gpio_port->puers = mask;
  404. } else {
  405. gpio_port->puerc = mask;
  406. }
  407. if (flags & GPIO_CFG_DEBOUNCE) {
  408. gpio_port->gfers = mask;
  409. } else {
  410. gpio_port->gferc = mask;
  411. }
  412. if (flags & GPIO_CFG_OUTPUT) {
  413. gpio_port->oders = mask;
  414. } else {
  415. gpio_port->oderc = mask;
  416. }
  417. if (flags & PERIPHERALS_MASK) {
  418. enable_module_pin(avr32_bank, mask, flags & PERIPHERALS_MASK);
  419. }
  420. if (flags & (GPIO_CFG_DISABLED | PERIPHERALS_MASK)) {
  421. gpio_port->gperc = mask;
  422. } else {
  423. gpio_port->gpers = mask;
  424. }
  425. #undef PERIPHERALS_MASK
  426. return 0;
  427. }
  428. /*!
  429. * \brief Set pin configuration.
  430. *
  431. * Applications may also use this function to make sure, that a specific
  432. * attribute is available for a specific pin.
  433. *
  434. * \note GPIO pins are typically initialized to a safe state after power
  435. * up. This routine is not able to determine the consequences of
  436. * changing pin configurations. In the worst case you may permanently
  437. * damage your hardware by bad pin settings.
  438. *
  439. * \param bank GPIO bank/port number.
  440. * \param bit Bit number of the specified bank/port.
  441. * \param flags Attribute flags.
  442. *
  443. * \return 0 if all attributes had been set, -1 otherwise.
  444. */
  445. int GpioPinConfigSet(int bank, int bit, uint32_t flags)
  446. {
  447. GpioPortConfigSet(bank, _BV(bit), flags);
  448. /* Check the result. */
  449. if (GpioPinConfigGet(bank, bit) != flags) {
  450. return -1;
  451. }
  452. return 0;
  453. }
  454. /*!
  455. * \brief Register a GPIO pin interrupt handler.
  456. *
  457. * Generating interrupts on GPIO pin changes is not supported on all
  458. * platforms. In this case dedicated external interrupt pins may
  459. * be used with NutRegisterIrqHandler().
  460. *
  461. * Interrupts are triggered on rising and falling edges. Level triggering
  462. * or triggering on specific edges is not supported.
  463. *
  464. * After registering, interrupts are disabled. Calling GpioIrqEnable()
  465. * is required to activate the interrupt.
  466. *
  467. * The following code fragment registers an interrupt handler which is
  468. * called on each change of bit 4 of the first GPIO port:
  469. * \code
  470. * #include <dev/gpio.h>
  471. *
  472. * static void PinChange(void *arg)
  473. * {
  474. * ...
  475. * }
  476. *
  477. * {
  478. * ...
  479. * GpioPinConfigSet(0, 4, GPIO_CFG_PULLUP);
  480. * GpioRegisterIrqHandler(&sig_GPIO, 4, PinChange, NULL);
  481. * GpioIrqEnable(&sig_GPIO, 30);
  482. * ...
  483. * }
  484. * \endcode
  485. *
  486. * \param sig Bank/port interrupt to be associated with this handler.
  487. * \param bit Bit number of the specified bank/port.
  488. * \param handler This routine will be called by Nut/OS, when the specified
  489. * pin changes its state.
  490. * \param arg Argument to be passed to the interrupt handler routine.
  491. *
  492. * \return 0 on success, -1 otherwise.
  493. */
  494. int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, int bit, void (*handler) (void *), void *arg)
  495. {
  496. int rc = 0;
  497. if (sig->ios_vector == 0) {
  498. /* This is the first call. Allocate the vector table. */
  499. sig->ios_vector = malloc(sizeof(GPIO_VECTOR) * 32);
  500. if (sig->ios_vector) {
  501. memset(sig->ios_vector, 0, sizeof(GPIO_VECTOR) * 32);
  502. if (sig->ios_ctl)
  503. rc = (sig->ios_ctl) (NUT_IRQCTL_INIT, NULL, bit);
  504. } else {
  505. rc = -1;
  506. }
  507. }
  508. sig->ios_vector[bit].iov_handler = handler;
  509. sig->ios_vector[bit].iov_arg = arg;
  510. return rc;
  511. }
  512. /*!
  513. * \brief Enable a specified GPIO interrupt.
  514. *
  515. * A related interrupt handler must have been registered before calling
  516. * this function. See GpioRegisterIrqHandler().
  517. *
  518. * \param sig Interrupt to enable.
  519. * \param bit Bit number of the specified bank/port.
  520. *
  521. * \return 0 on success, -1 otherwise.
  522. */
  523. int GpioIrqEnable(GPIO_SIGNAL * sig, int bit)
  524. {
  525. return (sig->ios_ctl) (NUT_IRQCTL_ENABLE, NULL, bit);
  526. }
  527. /*!
  528. * \brief Disable a specified GPIO interrupt.
  529. *
  530. * \param sig Interrupt to disable.
  531. * \param bit Bit number of the specified bank/port.
  532. *
  533. * \return 0 on success, -1 otherwise.
  534. */
  535. int GpioIrqDisable(GPIO_SIGNAL * sig, int bit)
  536. {
  537. return (sig->ios_ctl) (NUT_IRQCTL_DISABLE, NULL, bit);
  538. }
  539. /*!
  540. * \brief Set a specified GPIO interrupt mode.
  541. *
  542. * \param sig Interrupt to change mode.
  543. * \param bit Bit number of the specified bank/port.
  544. * \param mode Possible choices:
  545. * NUT_IRQMODE_RISINGEDGE
  546. * NUT_IRQMODE_FALLINGEDGE
  547. * NUT_IRQMODE_BOTHEDGE
  548. *
  549. * \return 0 on success, -1 otherwise.
  550. */
  551. int GpioIrqSetMode(GPIO_SIGNAL* sig, int bit, int mode)
  552. {
  553. return (sig->ios_ctl) (NUT_IRQCTL_SETMODE, &mode, bit);
  554. }