diff options
Diffstat (limited to 'keyboards/sol/serial.c')
| -rw-r--r-- | keyboards/sol/serial.c | 288 | 
1 files changed, 0 insertions, 288 deletions
| diff --git a/keyboards/sol/serial.c b/keyboards/sol/serial.c deleted file mode 100644 index 169b4b176c..0000000000 --- a/keyboards/sol/serial.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * WARNING: be careful changing this code, it is very timing dependent - */ - -#ifndef F_CPU -#define F_CPU 16000000 -#endif - -#include <avr/io.h> -#include <avr/interrupt.h> -#include <util/delay.h> -#include <stdbool.h> -#include "serial.h" - -#ifdef USE_SERIAL - -#define _delay_sub_us(x)    __builtin_avr_delay_cycles(x) - -// Serial pulse period in microseconds. -#define SELECT_SERIAL_SPEED 1 -#if SELECT_SERIAL_SPEED == 0 -  // Very High speed -  #define SERIAL_DELAY 4             // micro sec -  #define READ_WRITE_START_ADJUST 30 // cycles -  #define READ_WRITE_WIDTH_ADJUST 10 // cycles -#elif SELECT_SERIAL_SPEED == 1 -  // High speed -  #define SERIAL_DELAY 6             // micro sec -  #define READ_WRITE_START_ADJUST 23 // cycles -  #define READ_WRITE_WIDTH_ADJUST 10 // cycles -#elif SELECT_SERIAL_SPEED == 2 -  // Middle speed -  #define SERIAL_DELAY 12            // micro sec -  #define READ_WRITE_START_ADJUST 25 // cycles -  #define READ_WRITE_WIDTH_ADJUST 10 // cycles -#elif SELECT_SERIAL_SPEED == 3 -  // Low speed -  #define SERIAL_DELAY 24            // micro sec -  #define READ_WRITE_START_ADJUST 25 // cycles -  #define READ_WRITE_WIDTH_ADJUST 10 // cycles -#elif SELECT_SERIAL_SPEED == 4 -  // Very Low speed -  #define SERIAL_DELAY 50            // micro sec -  #define READ_WRITE_START_ADJUST 25 // cycles -  #define READ_WRITE_WIDTH_ADJUST 10 // cycles -#else -#error Illegal Serial Speed -#endif - - -#define SERIAL_DELAY_HALF1 (SERIAL_DELAY/2) -#define SERIAL_DELAY_HALF2 (SERIAL_DELAY - SERIAL_DELAY/2) - -#define SLAVE_INT_WIDTH 1 -#define SLAVE_INT_RESPONSE_TIME SERIAL_DELAY - -uint8_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0}; -uint8_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0}; - -#define SLAVE_DATA_CORRUPT (1<<0) -volatile uint8_t status = 0; - -inline static -void serial_delay(void) { -  _delay_us(SERIAL_DELAY); -} - -inline static -void serial_delay_half1(void) { -  _delay_us(SERIAL_DELAY_HALF1); -} - -inline static -void serial_delay_half2(void) { -  _delay_us(SERIAL_DELAY_HALF2); -} - -inline static -void serial_output(void) { -  SERIAL_PIN_DDR |= SERIAL_PIN_MASK; -} - -// make the serial pin an input with pull-up resistor -inline static -void serial_input_with_pullup(void) { -  SERIAL_PIN_DDR  &= ~SERIAL_PIN_MASK; -  SERIAL_PIN_PORT |= SERIAL_PIN_MASK; -} - -inline static -uint8_t serial_read_pin(void) { -  return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK); -} - -inline static -void serial_low(void) { -  SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK; -} - -inline static -void serial_high(void) { -  SERIAL_PIN_PORT |= SERIAL_PIN_MASK; -} - -void serial_master_init(void) { -  serial_output(); -  serial_high(); -} - -void serial_slave_init(void) { -  serial_input_with_pullup(); - - -// Enable INT3 -EIMSK |= _BV(INT3); -// Trigger on falling edge of INT3 -EICRA &= ~(_BV(ISC30) | _BV(ISC31)); - -} - -// Used by the sender to synchronize timing with the reciver. -static -void sync_recv(void) { -  for (int i = 0; i < SERIAL_DELAY*5 && serial_read_pin(); i++ ) { -  } -  // This shouldn't hang if the slave disconnects because the -  // serial line will float to high if the slave does disconnect. -  while (!serial_read_pin()); -} - -// Used by the reciver to send a synchronization signal to the sender. -static -void sync_send(void) { -  serial_low(); -  serial_delay(); -  serial_high(); -} - -// Reads a byte from the serial line -static -uint8_t serial_read_byte(void) { -  uint8_t byte = 0; -  _delay_sub_us(READ_WRITE_START_ADJUST); -  for ( uint8_t i = 0; i < 8; ++i) { -    serial_delay_half1();   // read the middle of pulses -    byte = (byte << 1) | serial_read_pin(); -    _delay_sub_us(READ_WRITE_WIDTH_ADJUST); -    serial_delay_half2(); -  } -  return byte; -} - -// Sends a byte with MSB ordering -static -void serial_write_byte(uint8_t data) { -  uint8_t b = 1<<7; -  while( b ) { -    if(data & b) { -      serial_high(); -    } else { -      serial_low(); -    } -    b >>= 1; -    serial_delay(); -  } -  serial_low(); // sync_send() / senc_recv() need raise edge -} - -// interrupt handle to be used by the slave device -ISR(SERIAL_PIN_INTERRUPT) { -  serial_output(); - -  // slave send phase -  uint8_t checksum = 0; -  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { -    sync_send(); -    serial_write_byte(serial_slave_buffer[i]); -    checksum += serial_slave_buffer[i]; -  } -  sync_send(); -  serial_write_byte(checksum); - -  // slave switch to input -  sync_send(); //0 -  serial_delay_half1(); //1 -  serial_low();         //2 -  serial_input_with_pullup(); //2 -  serial_delay_half1(); //3 - -  // slave recive phase -  uint8_t checksum_computed = 0; -  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { -    sync_recv(); -    serial_master_buffer[i] = serial_read_byte(); -    checksum_computed += serial_master_buffer[i]; -  } -  sync_recv(); -  uint8_t checksum_received = serial_read_byte(); - -  if ( checksum_computed != checksum_received ) { -    status |= SLAVE_DATA_CORRUPT; -  } else { -    status &= ~SLAVE_DATA_CORRUPT; -  } - -  sync_recv(); //weit master output to high -} - -inline -bool serial_slave_DATA_CORRUPT(void) { -  return status & SLAVE_DATA_CORRUPT; -} - -// Copies the serial_slave_buffer to the master and sends the -// serial_master_buffer to the slave. -// -// Returns: -// 0 => no error -// 1 => slave did not respond -// 2 => checksum error -int serial_update_buffers(void) { -  // this code is very time dependent, so we need to disable interrupts -  cli(); - -  // signal to the slave that we want to start a transaction -  serial_output(); -  serial_low(); -  _delay_us(SLAVE_INT_WIDTH); - -  // wait for the slaves response -  serial_input_with_pullup(); -  _delay_us(SLAVE_INT_RESPONSE_TIME); - -  // check if the slave is present -  if (serial_read_pin()) { -    // slave failed to pull the line low, assume not present -    serial_output(); -    serial_high(); -    sei(); -    return 1; -  } - -  // master recive phase -  // if the slave is present syncronize with it - -  uint8_t checksum_computed = 0; -  // receive data from the slave -  for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) { -    sync_recv(); -    serial_slave_buffer[i] = serial_read_byte(); -    checksum_computed += serial_slave_buffer[i]; -  } -  sync_recv(); -  uint8_t checksum_received = serial_read_byte(); - -  if (checksum_computed != checksum_received) { -    serial_output(); -    serial_high(); -    sei(); -    return 2; -  } - -  // master switch to output -  sync_recv(); //0 -  serial_delay();  //1 -  serial_low();    //3 -  serial_output(); // 3 -  serial_delay_half1(); //4 - -  // master send phase -  uint8_t checksum = 0; - -  for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) { -    sync_send(); -    serial_write_byte(serial_master_buffer[i]); -    checksum += serial_master_buffer[i]; -  } -  sync_send(); -  serial_write_byte(checksum); - -  // always, release the line when not in use -  sync_send(); - -  sei(); -  return 0; -} - -#endif | 
