I need to implement a protocol which require 8pins to output 20 bits of data in sync each cycle. The protocol is called XY2-100 and operates at 2MHz.
How do i write the pins simultaneousy?
Some detail:
I had a (almost) working solution on Teensy 3.6 but my code was to slow resulting in communication errors. I never got around to optimize more and since my knowledge is very limited most of the code is inspired by others and modified...
Now i want to get it working and i have high hopes with the performance boost of the teensy 4.0. So i tried compiling for T4 but got some errors which i do not completly understand other than i might have been using an inefficient way of solving my problem and adressing and setting up HW does not work the same on T4 as on th T3.6.
and in setup:
And while running write the data like below:
How do i write the pins simultaneousy?
Some detail:
I had a (almost) working solution on Teensy 3.6 but my code was to slow resulting in communication errors. I never got around to optimize more and since my knowledge is very limited most of the code is inspired by others and modified...
Now i want to get it working and i have high hopes with the performance boost of the teensy 4.0. So i tried compiling for T4 but got some errors which i do not completly understand other than i might have been using an inefficient way of solving my problem and adressing and setting up HW does not work the same on T4 as on th T3.6.
Code:
int pwm_pin_sync = 14; // PORT D1
int pwm_pin_sync_inv = 6; // PORT D1
int pwm_pin_clock = 18; // PORT B0 (18 Teensy 4.0 / 16 Teensy 3.6)
int pwm_pin_dataX = 7; // PORT D2 Chan 1+
int pwm_pin_dataX2 = 1; // PORT D6 (1 Teensy 4.0 / 21 Teensy 3.6)
int pwm_pin_dataY = 8; // PORT D3
int pwm_pin_dataY2 = 0; // PORT D5 (0 Teensy 4.0 / 20 Teensy 3.6)
Code:
void init_pwm(int khz) {
//pwm_pin_clock
// T3.6 CORE_PIN16_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE; // enable PWM
CORE_PIN18_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE; // enable PWM
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(0) | FTM_SC_TOF | FTM_SC_TOIE;
}
and in setup:
Code:
pinMode(pwm_pin_dataX, OUTPUT);
pinMode(pwm_pin_dataY, OUTPUT);
pinMode(pwm_pin_dataX2, OUTPUT);
pinMode(pwm_pin_dataY2, OUTPUT);
pinMode(pwm_pin_clock, OUTPUT);
pinMode(pwm_pin_sync, OUTPUT);
pinMode(pwm_pin_sync_inv, OUTPUT);
pinMode(LASER_TTL_PIN, OUTPUT);
ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
init_pwm(2000);
analogWriteFrequency(pwm_pin_clock, 200e4); // ~1usec period //YELLOW
analogWrite(pwm_pin_clock, 32768); // 50% duty for 16-bit range
FTM0_SYNC = 1;
FTM1_SYNC = 1;
FTM2_SYNC = 1;
attachInterrupt(digitalPinToInterrupt(pwm_pin_clock), data, FALLING);
#endif
And while running write the data like below:
Code:
void data()
{
// if(hasData != 0)
// {
uint32_t d = 2UL;
//WRITE SIGNAL
cbitx = activePacketX[bitCount];
cbity = activePacketY[bitCount];
d = (d & ~(1UL << 3)) | (cbity << 3); //PORT D3 --> pin8
d = (d & ~(1UL << 2)) | (cbitx << 2); //PORT D2 --> pin7
// WRITE INVERSE SIGNAL
d = (d & ~(1UL << 5)) | ((!cbity) << 5); //PORT D5 --> pin0
d = (d & ~(1UL << 6)) | ((!cbitx) << 6); //PORT D6 --> pin1
//WRITE SYNC
if(bitCount >= 19)
{
hasData = 0;
bitCount = -1;
d = (d & ~(1UL << 1)) | (0 << 1); // PORT D1 --> pin 14
d = (d & ~(1UL << 1)) | (1 << 4); // PORT D4 --> pin 6
}
GPIOD_PDOR = d;
bitCount++;
// }
}