Captain Jack
Member
Hi all
I have a Teensy 4.0 and I am trying to analyse an ASIC that communicates using serial data. The ASIC was used for non-standard crypto functions. I am communicating with it using a serial program on my computer via Teensy.
The ASIC communicates using 9-bit half-duplex at 38.4k baud and computer talks to Teensy at 9.6k baud. This is to allow the ASIC to process the input data and send back the answer at a higher speed.
So the flow of operations looks like this:
Host (computer) --> (Serial 3 @ 9600 baud) Teensy (Serial 2 @ 38400 baud) --> ASIC --> Teensy --> Host
This all works fine. However, given the nature of the ASIC, I would like to read various ASIC registers during data processing (it's LFSR chased with taps). As an example, to process a single byte through a crypto function takes multiples of 1024 clocks (1024, 2048, etc). Each clock equals an iteration through the function. The external clock speed is 3.58MHz, which can be stopped and started (to the ASIC that is) without loss of contents, so it's a fully static device.
With that said, what I would like to do is count the number of cycles between sending a byte to be processed and issuing a read command. For example, after sending a byte, I would like to wait 1 clock cycle and then send a read register command. The read command itself takes around 1280 clocks to process, so I won't be able to see the data from the start. Or issue a read before I send the byte to process. A lot of trial and error there.
I was thinking of utilising something like FreqCount but not sure if that's the best way to do this.
The alternative method is to generate the clock from Teensy itself and use that to drive the ASIC. Given that the ASIC is static (it's a 4000 gate array from what I understand), I could potentially stop and start the clock as required, or even slow down (I guess the serial baud will change too).
However, how do I say to Teensy; generate a clock of xMHz for n clocks and then stop. There's the analogWriteFrequency(PIN, SPEED) but that will just run and run.. again, I could count the clocks somehow and issue a stop (using analogWrite(4, 0)?) but it doesn't give me control that I ideally want.
I am looking for ideas and any code examples Here's what I have so far, though it doesn't really have anything to do with the question itself - just something to build up from.
I have a Teensy 4.0 and I am trying to analyse an ASIC that communicates using serial data. The ASIC was used for non-standard crypto functions. I am communicating with it using a serial program on my computer via Teensy.
The ASIC communicates using 9-bit half-duplex at 38.4k baud and computer talks to Teensy at 9.6k baud. This is to allow the ASIC to process the input data and send back the answer at a higher speed.
So the flow of operations looks like this:
Host (computer) --> (Serial 3 @ 9600 baud) Teensy (Serial 2 @ 38400 baud) --> ASIC --> Teensy --> Host
This all works fine. However, given the nature of the ASIC, I would like to read various ASIC registers during data processing (it's LFSR chased with taps). As an example, to process a single byte through a crypto function takes multiples of 1024 clocks (1024, 2048, etc). Each clock equals an iteration through the function. The external clock speed is 3.58MHz, which can be stopped and started (to the ASIC that is) without loss of contents, so it's a fully static device.
With that said, what I would like to do is count the number of cycles between sending a byte to be processed and issuing a read command. For example, after sending a byte, I would like to wait 1 clock cycle and then send a read register command. The read command itself takes around 1280 clocks to process, so I won't be able to see the data from the start. Or issue a read before I send the byte to process. A lot of trial and error there.
I was thinking of utilising something like FreqCount but not sure if that's the best way to do this.
The alternative method is to generate the clock from Teensy itself and use that to drive the ASIC. Given that the ASIC is static (it's a 4000 gate array from what I understand), I could potentially stop and start the clock as required, or even slow down (I guess the serial baud will change too).
However, how do I say to Teensy; generate a clock of xMHz for n clocks and then stop. There's the analogWriteFrequency(PIN, SPEED) but that will just run and run.. again, I could count the clocks somehow and issue a stop (using analogWrite(4, 0)?) but it doesn't give me control that I ideally want.
I am looking for ideas and any code examples Here's what I have so far, though it doesn't really have anything to do with the question itself - just something to build up from.
Code:
#define CONSOLE Serial
#define HOST Serial3
#define ASIC Serial2
#define CONSOLE_BAUD 115200
#define ASIC_BAUD 38400
#define HOST_BAUD 9600
#define HOST_ASIC 1
#define ASIC_HOST 3
uint16_t b;
int dir = ASIC_HOST;
int pdir = dir;
char fmt[64];
/* Reverse order of n bits in a byte */
static uint8_t _rev(uint8_t b, int n)
{
uint8_t r = 0;
while(n--)
{
r = (r << 1) | (b & 1);
b >>= 1;
}
return(r);
}
void sendByteToASIC(uint8_t a)
{
b = _rev(~(a), 8) << 1;
ASIC.write9bit(b | 1);
ASIC.flush();
delay(1);
}
void sendByteToHost(uint16_t b)
{
HOST.write(b);
HOST.flush();
delay(1);
}
void setup()
{
CONSOLE.begin(CONSOLE_BAUD);
ASIC.begin(ASIC_BAUD, SERIAL_9N1 | SERIAL_HALF_DUPLEX); /* ASIC -> HOST */
HOST.begin(HOST_BAUD, SERIAL_9N1 | SERIAL_HALF_DUPLEX); /* HOST -> ASIC */
}
void loop()
{
if(HOST.available() > 0)
{
dir = HOST_ASIC;
/* Received byte */
b = HOST.read() & 0xFF;
sprintf(fmt, "%s %02X", dir == pdir ? "" : "\n-->RQST:", b);
CONSOLE.print(fmt);
/* Resend byte from HOST to ASIC */
sendByteToASIC(b);
pdir = dir;
}
if(ASIC.available() > 0)
{
dir = ASIC_HOST;
/* Received byte */
b = ASIC.read();
b = _rev(~(b & 0xFF), 8);
/* Resend byte from ASIC to HOST */
sendByteToHost(b);
sprintf(fmt, "%s %02X", dir == pdir ? "" : "\n<--ASIC:", b);
CONSOLE.print(fmt);
pdir = dir;
}
}