summaryrefslogtreecommitdiffhomepage
path: root/digital/ucoolib/ucoolib/dev/avrisp/avrisp.hh
diff options
context:
space:
mode:
Diffstat (limited to 'digital/ucoolib/ucoolib/dev/avrisp/avrisp.hh')
-rw-r--r--digital/ucoolib/ucoolib/dev/avrisp/avrisp.hh247
1 files changed, 247 insertions, 0 deletions
diff --git a/digital/ucoolib/ucoolib/dev/avrisp/avrisp.hh b/digital/ucoolib/ucoolib/dev/avrisp/avrisp.hh
new file mode 100644
index 00000000..5046459b
--- /dev/null
+++ b/digital/ucoolib/ucoolib/dev/avrisp/avrisp.hh
@@ -0,0 +1,247 @@
+#ifndef ucoolib_dev_avrisp_avrisp_hh
+#define ucoolib_dev_avrisp_avrisp_hh
+// ucoolib - Microcontroller object oriented library. {{{
+//
+// Copyright (C) 2013 Nicolas Schodet
+//
+// APBTeam:
+// Web: http://apbteam.org/
+// Email: team AT apbteam DOT org
+//
+// 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, write to the Free Software
+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+//
+// }}}
+#include "ucoolib/common.hh"
+
+namespace ucoo {
+
+/// Results returned by ISP functions.
+enum AvrIspResult
+{
+ /// Operation success.
+ AVRISP_OK,
+ /// Operation failed.
+ AVRISP_FAILED,
+ /// Operation failed on a timeout.
+ AVRISP_TIMEOUT,
+};
+
+/// ISP Programming mode.
+enum AvrIspMode
+{
+ /// Use page programming.
+ AVRISP_MODE_PAGE = 1,
+ /// Use simple delay for word programming.
+ AVRISP_MODE_WORD_DELAY = 2,
+ /// Use value polling if possible for word programming, fall back to delay
+ /// if not possible.
+ AVRISP_MODE_WORD_VALUE = 4,
+ /// Use RDY/BSY polling for word programming.
+ AVRISP_MODE_WORD_RDY_BSY = 8,
+ /// Use simple delay for page programming.
+ AVRISP_MODE_PAGE_DELAY = 16,
+ /// Use value polling if possible for page programming, fall back to delay
+ /// if not possible.
+ AVRISP_MODE_PAGE_VALUE = 32,
+ /// Use RDY/BSY polling for page programming.
+ AVRISP_MODE_PAGE_RDY_BSY = 64,
+ /// Write page at end of transfer. Used for big pages which must be
+ /// transfered in several packets.
+ AVRISP_MODE_PAGE_WRITE = 128,
+};
+
+/// Interface to hardware connection.
+class AvrIspIntf
+{
+ public:
+ /// Send and receive one byte through SPI interface.
+ virtual uint8_t send_and_recv (uint8_t tx) = 0;
+ /// Enable programming:
+ /// - set RESET and SCK to low,
+ /// - power on, or if not possible, do a positive RESET pulse,
+ /// - enable SPI, mode 0.
+ virtual void enable (uint8_t sck_duration_us) = 0;
+ /// Disable programming:
+ /// - disable SPI,
+ /// - release RESET,
+ /// - power off if desired.
+ virtual void disable () = 0;
+ /// Do a pulse on SCK. This is used to try to resynchronise.
+ virtual void sck_pulse () = 0;
+};
+
+/// AVR serial programming.
+class AvrIsp
+{
+ public:
+ /// Constructor.
+ AvrIsp (AvrIspIntf &intf);
+ /// Enable SPI port and enter programing mode.
+ /// - sck_duration_us: SCK period.
+ /// - timeout_ms: command time-out, unused.
+ /// - stab_delay_ms: stabilisation delay once device is reseted and SPI
+ /// initialised.
+ /// - cmd_exe_delay_ms: delay for the command execution.
+ /// - synch_loops: number of synchronisation loops (there is no start of
+ /// frame in SPI).
+ /// - byte_delay_ms: delay between each byte.
+ /// - poll_value: value to read to consider the sequence is correct.
+ /// - poll_index: transfer index at which the poll_value must be read.
+ /// - cmd: command bytes to be transfered.
+ /// - returns: AVRISP_OK or AVRISP_FAILED if no synchronisation.
+ AvrIspResult enter_progmode (uint8_t sck_duration_us,
+ uint8_t timeout_ms, uint8_t stab_delay_ms,
+ uint8_t cmd_exe_delay_ms,
+ uint8_t synch_loops, uint8_t byte_delay_ms,
+ uint8_t poll_value, uint8_t poll_index,
+ const uint8_t cmd[4]);
+ /// Leave programming mode and disable SPI port.
+ /// - pre_delay_ms: delay before disabling.
+ /// - post_delay_ms: delay after disabling.
+ void leave_progmode (uint8_t pre_delay_ms, uint8_t post_delay_ms);
+ /// Load programing address.
+ /// - addr: address to load, bit 31 means the device has more than 64k
+ /// words and extended addressing should be used.
+ void load_address (uint32_t addr);
+ /// Chip full erase.
+ /// - erase_delay_ms: delay to ensure the erase is finished.
+ /// - poll_method: use delay (0) or RDY/BSY polling (1).
+ /// - cmd: chip erase command.
+ /// - returns: AVRISP_OK or AVRISP_TIMEOUT if using polling and it
+ /// timed-out.
+ AvrIspResult chip_erase (uint8_t erase_delay_ms, uint8_t poll_method,
+ const uint8_t cmd[4]);
+ /// Start a program command.
+ /// - num_bytes: total number of bytes to program.
+ /// - returns: AVRISP_OK or AVRISP_FAILED for bad parameters.
+ /// See class for other parameters meaning.
+ AvrIspResult program_begin (uint16_t num_bytes, uint8_t mode,
+ uint8_t delay_ms, uint8_t cmd_write_mem,
+ uint8_t cmd_write_page, uint8_t cmd_read_mem,
+ const uint8_t poll[2], uint8_t flash);
+ /// Start a flash memory program command.
+ /// - num_bytes: total number of bytes to program.
+ /// - returns: AVRISP_OK or AVRISP_FAILED for bad parameters.
+ /// See class for other parameters meaning.
+ AvrIspResult program_flash_begin (uint16_t num_bytes, uint8_t mode,
+ uint8_t delay_ms, uint8_t cmd_write_mem,
+ uint8_t cmd_write_page,
+ uint8_t cmd_read_mem,
+ const uint8_t poll[2]);
+ /// Start a EEPROM memory program command.
+ /// - num_bytes: total number of bytes to program.
+ /// - returns: AVRISP_OK or AVRISP_FAILED for bad parameters.
+ /// See class for other parameters meaning.
+ AvrIspResult program_eeprom_begin (uint16_t num_bytes,
+ uint8_t mode,
+ uint8_t delay_ms,
+ uint8_t cmd_write_mem,
+ uint8_t cmd_write_page,
+ uint8_t cmd_read_mem,
+ const uint8_t poll[2]);
+ /// Provide data for memory programming. Data should be given by even
+ /// sized packs or loading of word addressed data will fail.
+ /// - returns: AVRISP_OK, AVRISP_FAILED for bad parameters or
+ /// AVRISP_TIMEOUT if using polling and it timed-out.
+ AvrIspResult program_continue (const uint8_t *data, uint16_t size);
+ /// End program command.
+ /// - returns: AVRISP_OK, AVRISP_FAILED if too early or AVRISP_TIMEOUT if
+ /// using polling and it timed-out.
+ AvrIspResult program_end ();
+ /// Start a read command.
+ /// - num_bytes: total number of bytes to program.
+ /// - returns: AVRISP_OK or AVRISP_FAILED for bad parameters.
+ /// See class for other parameters meaning.
+ AvrIspResult read_begin (uint16_t num_bytes, uint8_t cmd_read_mem,
+ uint8_t flash);
+ /// Start a flash memory read command.
+ /// - num_bytes: total number of bytes to program.
+ /// - returns: AVRISP_OK or AVRISP_FAILED for bad parameters.
+ /// See class for other parameters meaning.
+ AvrIspResult read_flash_begin (uint16_t num_bytes, uint8_t cmd_read_mem);
+ /// Start a EEPROM memory read command.
+ /// - num_bytes: total number of bytes to program.
+ /// - returns: AVRISP_OK or AVRISP_FAILED for bad parameters.
+ /// See class for other parameters meaning.
+ AvrIspResult read_eeprom_begin (uint16_t num_bytes, uint8_t cmd_read_mem);
+ /// Get data from read memory. Data should be read by even sized packs or
+ /// loading of word addressed data will fail.
+ /// - returns: AVRISP_OK or AVRISP_FAILED for bad parameters.
+ AvrIspResult read_continue (uint8_t *data, uint16_t size);
+ /// End read command.
+ /// - returns: AVRISP_OK or AVRISP_FAILED if too early.
+ AvrIspResult read_end ();
+ /// Program miscellaneous memory (fuse, lock).
+ /// - cmd: program command.
+ void program_misc (const uint8_t cmd[4]);
+ /// Read miscellaneous memory (fuse, lock, signature, osccal).
+ /// - ret_addr: transfer index at which the return value must be read.
+ /// - cmd: read command.
+ uint8_t read_misc (uint8_t ret_addr, const uint8_t cmd[4]);
+ /// Generic SPI access.
+ /// - num_tx: number of bytes to transmit.
+ /// - num_rx: number of bytes to receive.
+ /// - rx_start: start reception after this number of transmitted bytes.
+ /// - dout: buffer to read sent bytes.
+ /// - din: buffer to write received bytes.
+ /// Limitation: no support for doing this in several chunks as memory
+ /// programing and reading.
+ void multi (uint8_t num_tx, uint8_t num_rx, uint8_t rx_start,
+ const uint8_t *dout, uint8_t *din);
+ private:
+ /// Transmit a 16 bit data.
+ void spi_tx_16 (uint16_t data);
+ /// Transmit a 32 bit data and return last byte received. This is used for
+ /// RDY/BSY polling.
+ uint8_t spi_tx_32 (uint32_t data);
+ private:
+ /// Hardware interface.
+ AvrIspIntf &intf_;
+ /// Current address.
+ uint16_t addr_;
+ /// Current extended address.
+ uint8_t ext_addr_;
+ /// Extended address loaded in device.
+ uint8_t last_ext_addr_;
+ /// Whether the device needs extended addressing.
+ uint8_t larger_than_64k_;
+ /// Programming start address (used for page program command).
+ uint16_t start_addr_;
+ /// Number of bytes left to process.
+ uint16_t bytes_left_;
+ /// Programming mode.
+ uint8_t mode_;
+ /// Programming delay if no other poll method.
+ uint8_t delay_ms_;
+ /// Write Program Memory or Load Page.
+ uint8_t cmd_write_mem_;
+ /// Write Page.
+ uint8_t cmd_write_page_;
+ /// Read Program Memory.
+ uint8_t cmd_read_mem_;
+ /// Value read until memory is programmed for value polling.
+ uint8_t poll_[2];
+ /// Whether the page can be polled (if almost one byte is not poll[0]).
+ /// This is non zero if true, with LSB = 1 for high byte.
+ uint8_t pollable_;
+ /// Address to use for polling.
+ uint16_t poll_addr_;
+ /// Whether this is a flash memory.
+ uint8_t flash_;
+};
+
+} // namespace ucoo
+
+#endif // ucoolib_dev_avrisp_avrisp_hh