jim herd / FPGA_bus
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FPGA_bus.h Source File

FPGA_bus.h

00001 /* 
00002  * FPGA_bus  :  8-bit bi-directional bus between uP and FPGA
00003  *
00004  * Author : Jim Herd
00005  *
00006  * Version 0.1 : initial release
00007  */
00008 #include "mbed.h"
00009 
00010 #ifndef  FPGA_bus_H
00011 #define  FPGA_bus_H
00012  
00013 //////////////////////////////////////////////////////////////////////////
00014 // MACROS
00015 
00016 #define LOOP_HERE     for(;;)
00017 
00018 //////////////////////////////////////////////////////////////////////////
00019 // Pin definitions
00020 
00021 #define ASYNC_UP_RW_PIN           PB_0
00022 #define ASYNC_UP_HANDSHAKE_1_PIN  PB_1
00023 #define ASYNC_UP_HANDSHAKE_2_PIN  PB_2
00024 #define ASYNC_UP_START_PIN        PB_3
00025 #define ASYNC_UP_ACK_PIN          PB_4
00026 #define ASYNC_UP_RESET_PIN        PB_5
00027 
00028 #define LOG_PIN                   PB_8
00029 
00030 //
00031 //#define PWM_BASE            1
00032 #define NOS_PWM_REGISTERS   4
00033 #define NOS_PWM_CHANNELS    1
00034 
00035 //#define QE_BASE             ((NOS_PWM_REGISTERS * NOS_PWM_CHANNELS) + PWM_BASE)
00036 #define NOS_QE_REGISTERS    7
00037 #define NOS_QE_CHANNELS     1
00038 
00039 //#define RC_BASE             ((NOS_QE_REGISTERS * NOS_QE_CHANNELS) + QE_BASE)
00040 #define NOS_RC_CHANNELS     8
00041 #define GLOBAL_RC_ENABLE    0x80000000
00042 
00043 #define PWM_ch0             (PWM_base + (0 * NOS_PWM_REGISTERS))
00044 #define PWM_ch1             (PWM_base + (1 * NOS_PWM_REGISTERS))
00045 #define PWM_ch3             (PWM_base + (3 * NOS_PWM_REGISTERS))
00046 
00047 #define RC_0                RC_BASE
00048 
00049 //
00050 // System can be configured to return ONE or TWO 32-bit values from the FPGA.
00051 //
00052 //      first value  : 32-bit data value
00053 //      second value : 32-bit status value
00054 //
00055 // In practice, the status word carries little or no information but consumes
00056 // four 8-bit transactions between the FPGA and the uP.
00057 //
00058 // Uncomment following #define to enable status word to be returned.
00059 
00060 //#define INCLUDE_32_BIT_STATUS_RETURN
00061 
00062 #ifdef INCLUDE_32_BIT_STATUS_RETURN
00063     #define NOS_RECEIVED_PACKET_WORDS  2
00064 #else
00065     #define NOS_RECEIVED_PACKET_WORDS  1
00066 #endif
00067 
00068 #define SET_BUS_INPUT             (GPIOC->MODER = (GPIOC->MODER & 0xFFFF0000))
00069 #define SET_BUS_OUTPUT            (GPIOC->MODER = ((GPIOC->MODER & 0xFFFF0000) | 0x00005555))
00070 #define OUTPUT_BYTE_TO_BUS(value) (GPIOC->ODR = ((GPIOC->ODR & 0x0000FF00) | (value & 0x000000FF)))
00071 #define INPUT_BYTE_FROM_BUS       (GPIOC->IDR & 0x000000FF)
00072 #define ENABLE_GPIO_SUBSYSTEM     (RCC->AHBENR |= RCC_AHBENR_GPIOCEN)
00073 
00074 //////////////////////////////////////////////////////////////////////////
00075 // FPGA constants
00076 
00077 #define     nS_IN_uS                          1000
00078 #define     FPGA_CLOCK_PERIOD_nS                20
00079 #define     uS_DELAY_BEFORE_TEST_HANDSHAKE      25
00080 #define     HANDSHAKE_TIMEOUT_COUNT          10000
00081 #define     FPGA_RESET_PULSE_WIDTH              20    // microseconds
00082 
00083 //////////////////////////////////////////////////////////////////////////
00084 // error codes
00085 
00086 #define     NO_ERROR      0
00087 #define     BUS_FAIL_1  -31     // handshake_2 initially HIGH but should be LOW
00088 #define     BUS_FAIL_2  -32     // handshake_2 not transitioned to HIGH
00089 #define     BUS_FAIL_3  -33     // handshake_2 not transitioned to HIGH
00090 
00091 //////////////////////////////////////////////////////////////////////////
00092 // typedef structures
00093 
00094 typedef struct {
00095     uint8_t     command;
00096     uint8_t     register_no;
00097     uint32_t    cmd_data;
00098     uint32_t    reply_data;
00099     uint32_t    reply_status;
00100 } FPGA_packet_t;
00101 
00102 typedef union {
00103     uint32_t word_data[2];    // NOS_RECEIVED_PACKET_WORDS];
00104     uint8_t  byte_data[8];    // NOS_RECEIVED_PACKET_WORDS << 2];
00105 } received_packet_t;
00106 
00107 enum {READ_REGISTER_CMD=0, WRITE_REGISTER_CMD=1};
00108 enum {READ_BUS=0, WRITE_BUS=1};
00109 enum {LOW=0, HIGH=1};
00110 
00111 //////////////////////////////////////////////////////////////////////////
00112 // SYS_data registers
00113 
00114 enum {SYS_DATA_REG_ADDR=0};
00115 
00116 //////////////////////////////////////////////////////////////////////////
00117 // PWM registers with relative addresses
00118 //
00119 enum {PWM_PERIOD=0, PWM_ON_TIME=1, PWM_CONFIG=2, PWM_STATUS=3};
00120 //
00121 // constants to define bits in PWM config register
00122 
00123 #define  PWM_CONFIG_DEFAULT    0x00
00124 enum {PWM_OFF=0x0, PWM_ON=0x1};
00125 enum {INT_H_BRIDGE_OFF=0x0, INT_H_BRIDGE_ON=0x10000};
00126 enum {EXT_H_BRIDGE_OFF=0x0, EXT_H_BRIDGE_ON=0x20000};
00127 enum {MODE_PWM_CONTROL=0x0, MODE_DIR_CONTROL=0x40000};
00128 enum {MOTOR_COAST=0x0, MOTOR_FORWARD=0x100000, MOTOR_BACKWARD=0x200000, MOTOR_BRAKE=0x300000};
00129 enum {NO_SWAP=0x0, YES_SWAP=0x1000000};
00130 enum {PWM_BRAKE_DWELL=0x0, PWM_COAST_DWELL=0x2000000};
00131 enum {NO_INVERT = 0x0, H_BRIDGE_1_INVERT=0x4000000, H_BRIDGE_2_INVERT=0x8000000, ALL_INVERT=0xC000000};
00132 enum {BACKWARD, FORWARD};
00133 
00134 //////////////////////////////////////////////////////////////////////////
00135 // QE registers with relative addresses
00136 //
00137 enum {QE_COUNT_BUFFER=0, QE_TURN_BUFFER=1, QE_SPEED_BUFFER=2, QE_SIM_PHASE_TIME=3,
00138       QE_COUNTS_PER_REV=4, QE_CONFIG=5, QE_STATUS=6};
00139 //
00140 // constants to define bits in QE config register
00141 
00142 #define  QE_CONFIG_DEFAULT    0x00
00143 enum {QE_SIG_EXT=0x00, QE_SIG_INT_SIM=0x02};
00144 enum {QE_INT_SIM_DISABLE=0x0, QE_INT_SIM_ENABLE=0x04};
00145 enum {QE_SIM_DIR_FORWARD=0x0, QE_SIM_DIR_BACKWARD=0x08};
00146 enum {QE_NO_SWAP_AB=0x00, QE_SWAP_AB=0x10};
00147 enum {QE_SPEED_CALC_DISABLE=0x00, QE_SPEED_CALC_ENABLE=0x10000};
00148 enum {QE_SPEED_CALC_FILTER_DISABLE=0x00, QE_SPEED_CALC_FILTER_ENABLE=0x20000};
00149 enum {QE_FILTER_SAMPLE_2=0x00, QE_FILTER_SAMPLE_4=0x100000, QE_FILTER_SAMPLE_8=0x200000,
00150       QE_FILTER_SAMPLE_16=0x300000, QE_FILTER_SAMPLE_32=0x400000};
00151 
00152 //////////////////////////////////////////////////////////////////////////   
00153 // RC servo registers with relative addresses
00154 //
00155 enum {RC_SERVO_PERIOD=0, RC_SERVO_CONFIG=1, RC_SERVO_STATUS=2, RC_SERVO_ON_TIME=3};
00156 
00157 //////////////////////////////////////////////////////////////////////////
00158 // FPGA_bus class
00159 // ==============
00160 
00161 class FPGA_bus {
00162 public:
00163      FPGA_bus(int nos_PWM    = NOS_PWM_CHANNELS , 
00164               int nos_QE     = NOS_QE_CHANNELS  , 
00165               int nos_servo  = NOS_RC_CHANNELS   );  // constructor
00166 //
00167 // functions
00168 // 
00169     int32_t   initialise(void); 
00170     void      do_transaction(uint32_t command, 
00171                              uint32_t register_address, 
00172                              uint32_t register_data,
00173                              uint32_t *data,
00174                              uint32_t *status);
00175      void     write_register(uint32_t register_addr, uint32_t value);
00176      void     set_PWM_period(uint32_t channel, float frequency);
00177      void     set_PWM_duty(uint32_t channel, float percentage);
00178      void     PWM_enable(uint32_t channel);
00179      void     PWM_config(uint32_t channel, uint32_t config_value);
00180      void     set_RC_period(void);
00181      void     set_RC_period(uint32_t duty_uS);
00182      void     set_RC_pulse(uint32_t channel, uint32_t pulse_uS);
00183      void     enable_RC_channel(uint32_t channel);
00184      void     disable_RC_channel(uint32_t channel);
00185      void     QE_config(uint32_t channel, uint32_t config_value);
00186      void     enable_speed_measure(uint32_t channel, uint32_t config_value, uint32_t phase_time);
00187      uint32_t read_speed_measure(uint32_t channel);
00188      uint32_t read_count_measure(uint32_t channel);
00189      uint32_t get_SYS_data(void);
00190      int32_t  soft_check_bus(void);
00191      int32_t  hard_check_bus(void);
00192 //
00193 // data
00194 //   
00195      int32_t global_FPGA_unit_error_flag;
00196      uint32_t    PWM_base, QE_base, RC_base;
00197 //
00198 // persistant system data
00199 //
00200      struct SYS_data {
00201         uint8_t major_version;
00202         uint8_t minor_version;
00203         uint8_t number_of_PWM_channels;
00204         uint8_t number_of_QE_channels;
00205         uint8_t number_of_RC_channels;
00206         uint32_t PWM_period_value[NOS_PWM_CHANNELS];
00207         uint32_t PWM_duty_value[NOS_PWM_CHANNELS];
00208      } sys_data;
00209      
00210 private:
00211 //
00212 // data
00213 //
00214     uint32_t    _nos_PWM_units;
00215     uint32_t    _nos_QE_units;
00216     uint32_t    _nos_servo_units;
00217     
00218     uint32_t data, status, tmp_config;
00219     received_packet_t   in_pkt;
00220 //
00221 // functions
00222 //
00223     void     do_start(void);
00224     void     do_end(void);
00225     void     write_byte(uint32_t byte_value);
00226     uint32_t read_byte(void);
00227     void     do_write(  uint32_t command, 
00228                         uint32_t register_address, 
00229                         uint32_t register_data);
00230     void     do_read(received_packet_t   *buffer);
00231     void     do_reset(void);
00232     void     update_FPGA_register_pointers(void);
00233 //
00234 // Hardware digital I/O lines
00235 //    
00236     DigitalOut async_uP_start;
00237     DigitalOut async_uP_handshake_1;
00238     DigitalOut async_uP_RW;
00239     DigitalOut async_uP_reset;
00240     DigitalIn  uP_ack;
00241     DigitalIn  uP_handshake_2;
00242     
00243     DigitalOut log_pin;
00244     
00245 };
00246  
00247  #endif
00248