Talking about the function DSR, in the AJAWe programmer, I think that the Zenner diode D5 is labeled wrong. In fact, the circuit makes sense only if we assume that DSR is high when the supply voltage VCC reaches a level of 3V.
In other words, the DSR is used to signal that the circuit power, and he can work properly. And it seems that the original programmer made the same assumption.
My patch check the DSR to emulate the original programmer operation.
Of course, there is nothing wrong if we assume that the programmer AJAWe is permanently connected, because the DSR status check isn't, however, a very good method for identifying the used programmer. And, yes, I agree with your changes.
All the best, Virgil-Adrian.
On Fri, Aug 31, 2012 at 10:40 AM, Stefan Tauner stefan.tauner@student.tuwien.ac.at wrote:
http://www.ajawe.pl/ajawe0208.htm http://www.ajawe.pl/files/0208_R_DOK.pdf
First version was Signed-off-by: Virgil-Adrian Teaca darkstarlinux@gmail.com Refinements and general cleanup is Signed-off-by: Stefan Tauner stefan.tauner@student.tuwien.ac.at
Virgil: could you please take a look at this and maybe even test it? i have changed a few bits of your patch, most of it shouldnt change behavior, with one major exception: AJAWe is always assumed to be attached. this should not be a big issue the worst thing that could happen is that we toggle a few bits of an unknown device, but OTOH even if your detection would work it is not really safe, but just a good guess (this also applies to some extent to the SI-Prog detection).
if i interpret the AJAWe schematic correctly, then it sets pin 6 (DSR) high if there is too much voltage on VCC and low otherwise. it does so by two times inverting the voltage level that remains after subtracting 3.3V (with the zener diode D5) from VCC. the trigger voltage of the schmitt triggers is about 2V, so this would result DSR being high only if the voltage rises above abot 5.3V. this looks more like an overvoltage signaling than a power inidicator to me. OTOH i am bad at electronics... we need to check this with someone who knows what he is doing :)
pony_spi.c | 171 +++++++++++++++++++++++++++++++++++++++--------------------- print.c | 2 +- 2 files changed, 113 insertions(+), 60 deletions(-)
diff --git a/pony_spi.c b/pony_spi.c index fb90a33..7875200 100644 --- a/pony_spi.c +++ b/pony_spi.c @@ -17,8 +17,27 @@
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/* Driver for the SI-Prog like hardware by Lancos.com.
- See http://www.lancos.com/siprogsch.html for schematics and instructions.
+/* Driver for serial programmers compatible with SI-Prog or AJAWe.
- See http://www.lancos.com/siprogsch.html for SI-Prog schematics and instructions.
- See http://www.ajawe.pl/ajawe0208.htm for AJAWe serial programmer documentation.
- Pin layout for SI-Prog-like hardware:
- MOSI <-------< DTR
- MISO >-------> CTS
- SCK <---+---< RTS
+---> DSR
- CS# <-------< TXD
- and for the AJAWe serial programmer:
- MOSI <-------< DTR
- MISO >-------> CTS
- SCK <-------< RTS
- CS# <-------< TXD
*/
- DCE >-------> DSR
#include <stdlib.h> @@ -28,55 +47,50 @@ #include "flash.h" #include "programmer.h"
-/* We have:
- MOSI -----> DTR
- MISO -----> CTS
- SCK --+--> RTS
+--> DSR
- CS# -----> TXD
-*/
enum pony_type { TYPE_SI_PROG, TYPE_SERBANG,
TYPE_AJAWE
};
-/* The hardware programmer used. */ -static enum pony_type pony_type = TYPE_SI_PROG; +/* Pins for master->slave direction */ +static int pony_negate_cs = 1; +static int pony_negate_sck = 0; +static int pony_negate_mosi = 0; +/* Pins for slave->master direction */ +static int pony_negate_miso = 0;
static void pony_bitbang_set_cs(int val) {
if (pony_type == TYPE_SI_PROG)
{
/* CS# is negated by the SI-Prog programmer. */
if (pony_negate_cs) val ^= 1;
}
sp_set_pin(PIN_TXD, val);
}
static void pony_bitbang_set_sck(int val) {
if (pony_negate_sck)
val ^= 1;
sp_set_pin(PIN_RTS, val);
}
static void pony_bitbang_set_mosi(int val) {
if (pony_negate_mosi)
val ^= 1;
sp_set_pin(PIN_DTR, val);
}
static int pony_bitbang_get_miso(void) {
int tmp;
tmp = sp_get_pin(PIN_CTS);
int tmp = sp_get_pin(PIN_CTS);
if (pony_type == TYPE_SERBANG)
{
/* MISO is negated by the SERBANG programmer. */
if (pony_negate_miso) tmp ^= 1;
}
return tmp;
}
@@ -91,15 +105,17 @@ static const struct bitbang_spi_master bitbang_spi_master_pony = {
int pony_spi_init(void) {
int i, data_out; char *arg = NULL;
int i, data_in, data_out, have_device = 0;
int have_prog = 1;
enum pony_type type = TYPE_SI_PROG;
char *name;
int have_device = 0;
int have_prog = 0;
/* The parameter is on format "dev=/dev/device,type=serbang" */
/* The parameter is in format "dev=/dev/device,type=serbang" */ arg = extract_programmer_param("dev");
if (arg && strlen(arg)) {
sp_fd = sp_openserport( arg, 9600 );
sp_fd = sp_openserport(arg, 9600); if (sp_fd < 0) { free(arg); return 1;
@@ -110,51 +126,88 @@ int pony_spi_init(void)
if (!have_device) { msg_perr("Error: No valid device specified.\n"
"Use flashrom -p pony_spi:dev=/dev/device\n");
"Use flashrom -p pony_spi:dev=/dev/device[,type=name]\n"); return 1; }
/* Register the shutdown callback. */
if (register_shutdown(serialport_shutdown, NULL)) {
arg = extract_programmer_param("type");
if (arg && !strcasecmp(arg, "serbang")) {
type = TYPE_SERBANG;
} else if (arg && !strcasecmp(arg, "si_prog")) {
type = TYPE_SI_PROG;
} else if (arg && !strcasecmp( arg, "ajawe")) {
type = TYPE_AJAWE;
} else if (arg && !strlen(arg)) {
msg_perr("Error: Missing argument for programmer type.\n");
free(arg);
} else if (arg){
msg_perr("Error: Invalid programmer type specified.\n");
free(arg); return 1; }
arg = extract_programmer_param("type");
free(arg);
if (arg) {
if (!strcasecmp( arg, "serbang")) {
pony_type = TYPE_SERBANG;
} else if (!strcasecmp( arg, "si_prog") ) {
pony_type = TYPE_SI_PROG;
} else {
msg_perr("Error: Invalid programmer type specified.\n");
free(arg);
return 1;
}
/*
* Configure the serial port pins, depending on the used programmer.
*/
switch (type) {
case TYPE_AJAWE:
pony_negate_cs = 1;
pony_negate_sck = 1;
pony_negate_mosi = 1;
pony_negate_miso = 1;
name = "AJAWe";
break;
case TYPE_SERBANG:
pony_negate_cs = 0;
pony_negate_sck = 0;
pony_negate_mosi = 0;
pony_negate_miso = 1;
name = "serbang";
break;
default:
case TYPE_SI_PROG:
pony_negate_cs = 1;
pony_negate_sck = 0;
pony_negate_mosi = 0;
pony_negate_miso = 0;
name = "SI-Prog";
break; }
free(arg);
msg_pdbg("Using %s programmer pinout.\n", name);
msg_pdbg("Using the %s programmer.\n", ((pony_type == TYPE_SI_PROG ) ? "SI-Prog" : "SERBANG")); /*
* Detect if there is a SI-Prog compatible programmer connected.
* Detect if there is a compatible hardware programmer connected. */ pony_bitbang_set_cs(1);
pony_bitbang_set_sck(1); pony_bitbang_set_mosi(1);
/* We toggle SCK while we keep MOSI and CS# on. */
for (i = 1; i <= 10; ++i) {
data_out = i & 1;
sp_set_pin(PIN_RTS, data_out);
programmer_delay( 1000 );
data_in = sp_get_pin(PIN_DSR);
if (data_out != data_in) {
have_prog = 0;
break;
switch (type) {
case TYPE_AJAWE:
have_prog = 1;
break;
case TYPE_SI_PROG:
case TYPE_SERBANG:
default:
have_prog = 1;
/* We toggle RTS/SCK a few times and see if DSR changes too. */
for (i = 1; i <= 10; i++) {
data_out = i & 1;
sp_set_pin(PIN_RTS, data_out);
programmer_delay(1000);
/* If DSR does not change, we are not connected to what we think */
if (data_out != sp_get_pin(PIN_DSR)) {
have_prog = 0;
break;
} }
break; } if (!have_prog) {
msg_perr( "No SI-Prog compatible hardware detected.\n" );
msg_perr("No programmer compatible with %s detected.\n", name); return 1; }
diff --git a/print.c b/print.c index f0cd753..ae067a6 100644 --- a/print.c +++ b/print.c @@ -520,7 +520,7 @@ void print_supported(void) msg_ginfo("\nSupported devices for the %s programmer:\n", programmer_table[PROGRAMMER_PONY_SPI].name); /* FIXME */
msg_ginfo("SI-Prog and SERBANG serial port programmer\n");
msg_ginfo("SI-Prog, serbang and AJAWe serial port programmers\n");
#endif #if CONFIG_NICINTEL == 1 msg_ginfo("\nSupported devices for the %s programmer:\n", -- Kind regards, Stefan Tauner