Comms between MAX 10 FPGA and ST uP
FPGA_bus.h@1:b819a72b3b5d, 2019-04-17 (annotated)
- Committer:
- jimherd
- Date:
- Wed Apr 17 14:32:22 2019 +0000
- Revision:
- 1:b819a72b3b5d
- Parent:
- 0:9600ed6fd725
- Child:
- 2:fd5c862b86db
Added higher level routines to set RC channels.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jimherd | 0:9600ed6fd725 | 1 | /* |
jimherd | 0:9600ed6fd725 | 2 | * FPGA_bus : 8-bit bi-directional bus between uP and FPGA |
jimherd | 0:9600ed6fd725 | 3 | * |
jimherd | 0:9600ed6fd725 | 4 | * Author : Jim Herd |
jimherd | 0:9600ed6fd725 | 5 | * |
jimherd | 0:9600ed6fd725 | 6 | * Version 0.1 : initial release |
jimherd | 0:9600ed6fd725 | 7 | */ |
jimherd | 0:9600ed6fd725 | 8 | #include "mbed.h" |
jimherd | 0:9600ed6fd725 | 9 | |
jimherd | 0:9600ed6fd725 | 10 | #ifndef FPGA_bus_H |
jimherd | 0:9600ed6fd725 | 11 | #define FPGA_bus_H |
jimherd | 0:9600ed6fd725 | 12 | |
jimherd | 0:9600ed6fd725 | 13 | // |
jimherd | 0:9600ed6fd725 | 14 | // Pin definitions |
jimherd | 0:9600ed6fd725 | 15 | |
jimherd | 0:9600ed6fd725 | 16 | #define ASYNC_UP_RW_PIN PB_0 |
jimherd | 0:9600ed6fd725 | 17 | #define ASYNC_UP_HANDSHAKE_1_PIN PB_1 |
jimherd | 0:9600ed6fd725 | 18 | #define ASYNC_UP_HANDSHAKE_2_PIN PB_2 |
jimherd | 0:9600ed6fd725 | 19 | #define ASYNC_UP_START_PIN PB_3 |
jimherd | 0:9600ed6fd725 | 20 | #define ASYNC_UP_ACK_PIN PB_4 |
jimherd | 0:9600ed6fd725 | 21 | #define ASYNC_UP_RESET_PIN PB_5 |
jimherd | 0:9600ed6fd725 | 22 | |
jimherd | 0:9600ed6fd725 | 23 | // |
jimherd | 0:9600ed6fd725 | 24 | // |
jimherd | 0:9600ed6fd725 | 25 | #define PWM_BASE 1 |
jimherd | 0:9600ed6fd725 | 26 | #define NOS_PWM_REGISTERS 4 |
jimherd | 0:9600ed6fd725 | 27 | #define NOS_PWM_CHANNELS 4 |
jimherd | 0:9600ed6fd725 | 28 | |
jimherd | 0:9600ed6fd725 | 29 | #define QE_BASE ((NOS_PWM_REGISTERS * NOS_PWM_CHANNELS) + PWM_BASE) |
jimherd | 0:9600ed6fd725 | 30 | #define NOS_QE_REGISTERS 7 |
jimherd | 0:9600ed6fd725 | 31 | #define NOS_QE_CHANNELS 4 |
jimherd | 0:9600ed6fd725 | 32 | |
jimherd | 0:9600ed6fd725 | 33 | #define RC_BASE ((NOS_QE_REGISTERS * NOS_QE_CHANNELS) + QE_BASE) |
jimherd | 0:9600ed6fd725 | 34 | #define NOS_RC_CHANNELS 8 |
jimherd | 0:9600ed6fd725 | 35 | |
jimherd | 0:9600ed6fd725 | 36 | #define PWM_ch0 (PWM_BASE + (0 * NOS_PWM_REGISTERS)) |
jimherd | 0:9600ed6fd725 | 37 | #define PWM_ch1 (PWM_BASE + (1 * NOS_PWM_REGISTERS)) |
jimherd | 0:9600ed6fd725 | 38 | #define PWM_ch3 (PWM_BASE + (3 * NOS_PWM_REGISTERS)) |
jimherd | 0:9600ed6fd725 | 39 | |
jimherd | 0:9600ed6fd725 | 40 | #define RC_0 RC_BASE |
jimherd | 0:9600ed6fd725 | 41 | |
jimherd | 0:9600ed6fd725 | 42 | #define NOS_RECEIVED_PACKET_WORDS 2 |
jimherd | 0:9600ed6fd725 | 43 | |
jimherd | 0:9600ed6fd725 | 44 | #define SET_BUS_INPUT (GPIOC->MODER = (GPIOC->MODER & 0xFFFF0000)) |
jimherd | 0:9600ed6fd725 | 45 | #define SET_BUS_OUTPUT (GPIOC->MODER = ((GPIOC->MODER & 0xFFFF0000) | 0x00005555)) |
jimherd | 0:9600ed6fd725 | 46 | #define OUTPUT_BYTE_TO_BUS(value) (GPIOC->ODR = ((GPIOC->ODR & 0x0000FF00) | (value & 0x000000FF))) |
jimherd | 0:9600ed6fd725 | 47 | #define INPUT_BYTE_FROM_BUS (GPIOC->IDR & 0x000000FF) |
jimherd | 0:9600ed6fd725 | 48 | #define ENABLE_GPIO_SUBSYSTEM (RCC->AHBENR |= RCC_AHBENR_GPIOCEN) |
jimherd | 0:9600ed6fd725 | 49 | |
jimherd | 1:b819a72b3b5d | 50 | // |
jimherd | 1:b819a72b3b5d | 51 | // FPGA constants |
jimherd | 1:b819a72b3b5d | 52 | |
jimherd | 1:b819a72b3b5d | 53 | #define nS_IN_uS 1000 |
jimherd | 1:b819a72b3b5d | 54 | #define FPGA_CLOCK_PERIOD_nS 20 |
jimherd | 1:b819a72b3b5d | 55 | |
jimherd | 1:b819a72b3b5d | 56 | // |
jimherd | 1:b819a72b3b5d | 57 | // error codes |
jimherd | 1:b819a72b3b5d | 58 | |
jimherd | 1:b819a72b3b5d | 59 | #define NO_ERROR 0 |
jimherd | 1:b819a72b3b5d | 60 | |
jimherd | 0:9600ed6fd725 | 61 | #define LOOP_HERE for(;;) |
jimherd | 0:9600ed6fd725 | 62 | |
jimherd | 0:9600ed6fd725 | 63 | typedef struct { |
jimherd | 0:9600ed6fd725 | 64 | uint8_t command; |
jimherd | 0:9600ed6fd725 | 65 | uint8_t register_no; |
jimherd | 0:9600ed6fd725 | 66 | uint32_t cmd_data; |
jimherd | 0:9600ed6fd725 | 67 | uint32_t reply_data; |
jimherd | 0:9600ed6fd725 | 68 | uint32_t reply_status; |
jimherd | 0:9600ed6fd725 | 69 | } FPGA_packet_t; |
jimherd | 0:9600ed6fd725 | 70 | |
jimherd | 0:9600ed6fd725 | 71 | typedef union { |
jimherd | 0:9600ed6fd725 | 72 | uint32_t word_data[NOS_RECEIVED_PACKET_WORDS]; |
jimherd | 0:9600ed6fd725 | 73 | uint8_t byte_data[NOS_RECEIVED_PACKET_WORDS << 2]; |
jimherd | 0:9600ed6fd725 | 74 | } received_packet_t; |
jimherd | 0:9600ed6fd725 | 75 | |
jimherd | 0:9600ed6fd725 | 76 | enum {READ_REGISTER_CMD=0, WRITE_REGISTER_CMD=1}; |
jimherd | 0:9600ed6fd725 | 77 | enum {READ_BUS=0, WRITE_BUS=1}; |
jimherd | 0:9600ed6fd725 | 78 | enum {LOW=0, HIGH=1}; |
jimherd | 0:9600ed6fd725 | 79 | enum {PWM_PERIOD=0, PWM_ON_TIME=1, PWM_CONFIG=2, PWM_STATUS=3}; |
jimherd | 0:9600ed6fd725 | 80 | |
jimherd | 0:9600ed6fd725 | 81 | enum {RC_SERVO_PERIOD=0, RC_SERVO_CONFIG=1, RC_SERVO_STATUS=2, RC_SERVO_ON_TIME=3}; |
jimherd | 0:9600ed6fd725 | 82 | |
jimherd | 0:9600ed6fd725 | 83 | enum {PWM_OFF=0x0, PWM_ON=0x1}; |
jimherd | 0:9600ed6fd725 | 84 | enum {INT_H_BRIDGE_OFF=0x0, INT_H_BRIDGE_ON=0x10000}; |
jimherd | 0:9600ed6fd725 | 85 | enum {EXT_H_BRIDGE_OFF=0x0, EXT_H_BRIDGE_ON=0x20000}; |
jimherd | 0:9600ed6fd725 | 86 | enum {MOTOR_COAST=0x0, MOTOR_FORWARD=0x40000, MOTOR_BACKWARD=0x80000, MOTOR_BRAKE=0xC0000}; |
jimherd | 0:9600ed6fd725 | 87 | enum {MODE_PWM_CONTROL=0x0, MODE_DIR_CONTROL=0x200000}; |
jimherd | 0:9600ed6fd725 | 88 | enum {NO_SWAP=0x0, YES_SWAP=0x800000}; |
jimherd | 0:9600ed6fd725 | 89 | enum {PWM_BRAKE_DWELL=0x0, PWM_COAST_DWELL=0x1000000}; |
jimherd | 0:9600ed6fd725 | 90 | enum {NO_INVERT = 0x0, H_BRIDGE_1_INVERT=0x2000000, H_BRIDGE_2_INVERT=0x4000000, ALL_INVERT=0x6000000}; |
jimherd | 0:9600ed6fd725 | 91 | enum {BACKWARD, FORWARD}; |
jimherd | 0:9600ed6fd725 | 92 | |
jimherd | 0:9600ed6fd725 | 93 | //DigitalOut async_uP_start(ASYNC_UP_START_PIN, LOW); |
jimherd | 0:9600ed6fd725 | 94 | //DigitalOut async_uP_handshake_1(ASYNC_UP_HANDSHAKE_1_PIN, LOW); |
jimherd | 0:9600ed6fd725 | 95 | //DigitalOut async_uP_RW(ASYNC_UP_RW_PIN, LOW); |
jimherd | 0:9600ed6fd725 | 96 | //DigitalOut async_uP_reset(ASYNC_UP_RESET_PIN, HIGH); |
jimherd | 0:9600ed6fd725 | 97 | //DigitalIn uP_ack(ASYNC_UP_ACK_PIN, PullDown); |
jimherd | 0:9600ed6fd725 | 98 | //DigitalIn uP_handshake_2(ASYNC_UP_HANDSHAKE_2_PIN); |
jimherd | 0:9600ed6fd725 | 99 | |
jimherd | 0:9600ed6fd725 | 100 | class FPGA_bus { |
jimherd | 0:9600ed6fd725 | 101 | public: |
jimherd | 0:9600ed6fd725 | 102 | FPGA_bus(int nos_PWM, int nos_QE, int nos_servo); // constructor |
jimherd | 0:9600ed6fd725 | 103 | FPGA_bus(); // constructor |
jimherd | 0:9600ed6fd725 | 104 | |
jimherd | 0:9600ed6fd725 | 105 | void initialise(void); |
jimherd | 0:9600ed6fd725 | 106 | uint32_t do_command(FPGA_packet_t cmd_packet); |
jimherd | 1:b819a72b3b5d | 107 | void set_PWM_period(uint32_t channel, float frequency); |
jimherd | 1:b819a72b3b5d | 108 | void set_PWM_duty(uint32_t channel, float percentage); |
jimherd | 1:b819a72b3b5d | 109 | void PWM_enable(uint32_t channel); |
jimherd | 1:b819a72b3b5d | 110 | void PWM_config(uint32_t channel, uint32_t config_value); |
jimherd | 1:b819a72b3b5d | 111 | void set_RC_duty(void); |
jimherd | 1:b819a72b3b5d | 112 | void set_RC_duty(uint32_t duty_uS); |
jimherd | 1:b819a72b3b5d | 113 | void set_RC_pulse(uint32_t channel, uint32_t pulse_uS); |
jimherd | 1:b819a72b3b5d | 114 | void enable_RC_channel(uint32_t channel); |
jimherd | 1:b819a72b3b5d | 115 | |
jimherd | 1:b819a72b3b5d | 116 | int32_t global_FPGA_unit_error_flag; |
jimherd | 0:9600ed6fd725 | 117 | |
jimherd | 0:9600ed6fd725 | 118 | protected: |
jimherd | 0:9600ed6fd725 | 119 | uint32_t _nos_PWM_units; |
jimherd | 0:9600ed6fd725 | 120 | uint32_t _nos_QE_units; |
jimherd | 0:9600ed6fd725 | 121 | uint32_t _nos_servo_units; |
jimherd | 0:9600ed6fd725 | 122 | |
jimherd | 0:9600ed6fd725 | 123 | private: |
jimherd | 0:9600ed6fd725 | 124 | uint32_t data, status, tmp_config; |
jimherd | 0:9600ed6fd725 | 125 | received_packet_t in_pkt; |
jimherd | 0:9600ed6fd725 | 126 | |
jimherd | 0:9600ed6fd725 | 127 | void do_start(void); |
jimherd | 0:9600ed6fd725 | 128 | void do_end(void); |
jimherd | 0:9600ed6fd725 | 129 | void write_byte(uint32_t byte_value); |
jimherd | 0:9600ed6fd725 | 130 | uint32_t read_byte(void); |
jimherd | 0:9600ed6fd725 | 131 | void do_write( uint32_t command, |
jimherd | 0:9600ed6fd725 | 132 | uint32_t register_address, |
jimherd | 0:9600ed6fd725 | 133 | uint32_t register_data); |
jimherd | 0:9600ed6fd725 | 134 | void do_read(received_packet_t *buffer); |
jimherd | 0:9600ed6fd725 | 135 | void do_transaction(uint32_t command, |
jimherd | 0:9600ed6fd725 | 136 | uint32_t register_address, |
jimherd | 0:9600ed6fd725 | 137 | uint32_t register_data, |
jimherd | 0:9600ed6fd725 | 138 | uint32_t *data, |
jimherd | 0:9600ed6fd725 | 139 | uint32_t *status); |
jimherd | 0:9600ed6fd725 | 140 | |
jimherd | 0:9600ed6fd725 | 141 | DigitalOut async_uP_start; |
jimherd | 0:9600ed6fd725 | 142 | DigitalOut async_uP_handshake_1; |
jimherd | 0:9600ed6fd725 | 143 | DigitalOut async_uP_RW; |
jimherd | 0:9600ed6fd725 | 144 | DigitalOut async_uP_reset; |
jimherd | 0:9600ed6fd725 | 145 | DigitalIn uP_ack; |
jimherd | 0:9600ed6fd725 | 146 | DigitalIn uP_handshake_2; |
jimherd | 0:9600ed6fd725 | 147 | |
jimherd | 0:9600ed6fd725 | 148 | struct SYS_data { |
jimherd | 0:9600ed6fd725 | 149 | uint32_t PWM_period_value[NOS_PWM_CHANNELS]; |
jimherd | 0:9600ed6fd725 | 150 | uint32_t PWM_duty_value[NOS_PWM_CHANNELS]; |
jimherd | 0:9600ed6fd725 | 151 | } sys_data; |
jimherd | 0:9600ed6fd725 | 152 | }; |
jimherd | 0:9600ed6fd725 | 153 | |
jimherd | 0:9600ed6fd725 | 154 | #endif |
jimherd | 0:9600ed6fd725 | 155 |