Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/avrdude/serbb_posix.c')
-rw-r--r--src/avrdude/serbb_posix.c321
1 files changed, 321 insertions, 0 deletions
diff --git a/src/avrdude/serbb_posix.c b/src/avrdude/serbb_posix.c
new file mode 100644
index 000000000..319cfc9e4
--- /dev/null
+++ b/src/avrdude/serbb_posix.c
@@ -0,0 +1,321 @@
+/*
+ * avrdude - A Downloader/Uploader for AVR device programmers
+ * Copyright (C) 2000, 2001, 2002, 2003 Brian S. Dean <bsd@bsdhome.com>
+ * Copyright (C) 2005 Michael Holzt <kju-avr@fqdn.org>
+ * Copyright (C) 2006 Joerg Wunsch <j@uriah.heep.sax.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/* $Id$ */
+
+/*
+ * Posix serial bitbanging interface for avrdude.
+ */
+
+#if !defined(WIN32NATIVE)
+
+#include "ac_cfg.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+
+#include "avrdude.h"
+#include "libavrdude.h"
+
+#include "bitbang.h"
+#include "serbb.h"
+
+#undef DEBUG
+
+static struct termios oldmode;
+
+/*
+ serial port/pin mapping
+
+ 1 cd <-
+ 2 (rxd) <-
+ 3 txd ->
+ 4 dtr ->
+ 5 GND
+ 6 dsr <-
+ 7 rts ->
+ 8 cts <-
+ 9 ri <-
+*/
+
+#define DB9PINS 9
+
+static int serregbits[DB9PINS + 1] =
+{ 0, TIOCM_CD, 0, 0, TIOCM_DTR, 0, TIOCM_DSR, TIOCM_RTS, TIOCM_CTS, TIOCM_RI };
+
+#ifdef DEBUG
+static char *serpins[DB9PINS + 1] =
+ { "NONE", "CD", "RXD", "TXD", "DTR", "GND", "DSR", "RTS", "CTS", "RI" };
+#endif
+
+static int serbb_setpin(PROGRAMMER * pgm, int pinfunc, int value)
+{
+ unsigned int ctl;
+ int r;
+ int pin = pgm->pinno[pinfunc]; // get its value
+
+ if (pin & PIN_INVERSE)
+ {
+ value = !value;
+ pin &= PIN_MASK;
+ }
+
+ if ( pin < 1 || pin > DB9PINS )
+ return -1;
+
+#ifdef DEBUG
+ printf("%s to %d\n",serpins[pin],value);
+#endif
+
+ switch ( pin )
+ {
+ case 3: /* txd */
+ r = ioctl(pgm->fd.ifd, value ? TIOCSBRK : TIOCCBRK, 0);
+ if (r < 0) {
+ perror("ioctl(\"TIOCxBRK\")");
+ return -1;
+ }
+ break;
+
+ case 4: /* dtr */
+ case 7: /* rts */
+ r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMGET\")");
+ return -1;
+ }
+ if ( value )
+ ctl |= serregbits[pin];
+ else
+ ctl &= ~(serregbits[pin]);
+ r = ioctl(pgm->fd.ifd, TIOCMSET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMSET\")");
+ return -1;
+ }
+ break;
+
+ default: /* impossible */
+ return -1;
+ }
+
+ if (pgm->ispdelay > 1)
+ bitbang_delay(pgm->ispdelay);
+
+ return 0;
+}
+
+static int serbb_getpin(PROGRAMMER * pgm, int pinfunc)
+{
+ unsigned int ctl;
+ unsigned char invert;
+ int r;
+ int pin = pgm->pinno[pinfunc]; // get its value
+
+ if (pin & PIN_INVERSE)
+ {
+ invert = 1;
+ pin &= PIN_MASK;
+ } else
+ invert = 0;
+
+ if ( pin < 1 || pin > DB9PINS )
+ return(-1);
+
+ switch ( pin )
+ {
+ case 2: /* rxd, currently not implemented, FIXME */
+ return(-1);
+
+ case 1: /* cd */
+ case 6: /* dsr */
+ case 8: /* cts */
+ case 9: /* ri */
+ r = ioctl(pgm->fd.ifd, TIOCMGET, &ctl);
+ if (r < 0) {
+ perror("ioctl(\"TIOCMGET\")");
+ return -1;
+ }
+ if ( !invert )
+ {
+#ifdef DEBUG
+ printf("%s is %d\n",serpins[pin],(ctl & serregbits[pin]) ? 1 : 0 );
+#endif
+ return ( (ctl & serregbits[pin]) ? 1 : 0 );
+ }
+ else
+ {
+#ifdef DEBUG
+ printf("%s is %d (~)\n",serpins[pin],(ctl & serregbits[pin]) ? 0 : 1 );
+#endif
+ return (( ctl & serregbits[pin]) ? 0 : 1 );
+ }
+
+ default: /* impossible */
+ return(-1);
+ }
+}
+
+static int serbb_highpulsepin(PROGRAMMER * pgm, int pinfunc)
+{
+ int pin = pgm->pinno[pinfunc]; // replace pin name by its value
+
+ if ( (pin & PIN_MASK) < 1 || (pin & PIN_MASK) > DB9PINS )
+ return -1;
+
+ serbb_setpin(pgm, pinfunc, 1);
+ serbb_setpin(pgm, pinfunc, 0);
+
+ return 0;
+}
+
+
+
+static void serbb_display(PROGRAMMER *pgm, const char *p)
+{
+ /* MAYBE */
+}
+
+static void serbb_enable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_disable(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_powerup(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static void serbb_powerdown(PROGRAMMER *pgm)
+{
+ /* nothing */
+}
+
+static int serbb_open(PROGRAMMER *pgm, char *port)
+{
+ struct termios mode;
+ int flags;
+ int r;
+
+ if (bitbang_check_prerequisites(pgm) < 0)
+ return -1;
+
+ /* adapted from uisp code */
+
+ pgm->fd.ifd = open(port, O_RDWR | O_NOCTTY | O_NONBLOCK);
+
+ if (pgm->fd.ifd < 0) {
+ perror(port);
+ return(-1);
+ }
+
+ r = tcgetattr(pgm->fd.ifd, &mode);
+ if (r < 0) {
+ avrdude_message(MSG_INFO, "%s: ", port);
+ perror("tcgetattr");
+ return(-1);
+ }
+ oldmode = mode;
+
+ mode.c_iflag = IGNBRK | IGNPAR;
+ mode.c_oflag = 0;
+ mode.c_cflag = CLOCAL | CREAD | CS8 | B9600;
+ mode.c_cc [VMIN] = 1;
+ mode.c_cc [VTIME] = 0;
+
+ r = tcsetattr(pgm->fd.ifd, TCSANOW, &mode);
+ if (r < 0) {
+ avrdude_message(MSG_INFO, "%s: ", port);
+ perror("tcsetattr");
+ return(-1);
+ }
+
+ /* Clear O_NONBLOCK flag. */
+ flags = fcntl(pgm->fd.ifd, F_GETFL, 0);
+ if (flags == -1)
+ {
+ avrdude_message(MSG_INFO, "%s: Can not get flags: %s\n",
+ progname, strerror(errno));
+ return(-1);
+ }
+ flags &= ~O_NONBLOCK;
+ if (fcntl(pgm->fd.ifd, F_SETFL, flags) == -1)
+ {
+ avrdude_message(MSG_INFO, "%s: Can not clear nonblock flag: %s\n",
+ progname, strerror(errno));
+ return(-1);
+ }
+
+ return(0);
+}
+
+static void serbb_close(PROGRAMMER *pgm)
+{
+ if (pgm->fd.ifd != -1)
+ {
+ (void)tcsetattr(pgm->fd.ifd, TCSANOW, &oldmode);
+ pgm->setpin(pgm, PIN_AVR_RESET, 1);
+ close(pgm->fd.ifd);
+ }
+ return;
+}
+
+const char serbb_desc[] = "Serial port bitbanging";
+
+void serbb_initpgm(PROGRAMMER *pgm)
+{
+ strcpy(pgm->type, "SERBB");
+
+ pgm_fill_old_pins(pgm); // TODO to be removed if old pin data no longer needed
+
+ pgm->rdy_led = bitbang_rdy_led;
+ pgm->err_led = bitbang_err_led;
+ pgm->pgm_led = bitbang_pgm_led;
+ pgm->vfy_led = bitbang_vfy_led;
+ pgm->initialize = bitbang_initialize;
+ pgm->display = serbb_display;
+ pgm->enable = serbb_enable;
+ pgm->disable = serbb_disable;
+ pgm->powerup = serbb_powerup;
+ pgm->powerdown = serbb_powerdown;
+ pgm->program_enable = bitbang_program_enable;
+ pgm->chip_erase = bitbang_chip_erase;
+ pgm->cmd = bitbang_cmd;
+ pgm->cmd_tpi = bitbang_cmd_tpi;
+ pgm->open = serbb_open;
+ pgm->close = serbb_close;
+ pgm->setpin = serbb_setpin;
+ pgm->getpin = serbb_getpin;
+ pgm->highpulsepin = serbb_highpulsepin;
+ pgm->read_byte = avr_read_byte_default;
+ pgm->write_byte = avr_write_byte_default;
+}
+
+#endif /* WIN32NATIVE */