diff --git a/firmware/common/operacake.c b/firmware/common/operacake.c index 50bc9339..02d16851 100644 --- a/firmware/common/operacake.c +++ b/firmware/common/operacake.c @@ -22,36 +22,39 @@ #include "operacake.h" #include "hackrf_core.h" -#define OPERACAKE_PIN_OE (1<<7) -#define OPERACAKE_PIN_U2CTRL1 (1<<6) -#define OPERACAKE_PIN_U2CTRL0 (1<<5) -#define OPERACAKE_PIN_U3CTRL1 (1<<4) -#define OPERACAKE_PIN_U3CTRL0 (1<<3) -#define OPERACAKE_PIN_U1CTRL (1<<2) -#define OPERACAKE_PIN_LEDEN2 (1<<1) -#define OPERACAKE_PIN_LEDEN (1<<0) +#define OPERACAKE_PIN_OE(x) (x<<7) +#define OPERACAKE_PIN_U2CTRL1(x) (x<<6) +#define OPERACAKE_PIN_U2CTRL0(x) (x<<5) +#define OPERACAKE_PIN_U3CTRL1(x) (x<<4) +#define OPERACAKE_PIN_U3CTRL0(x) (x<<3) +#define OPERACAKE_PIN_U1CTRL(x) (x<<2) +#define OPERACAKE_PIN_LEDEN2(x) (x<<1) +#define OPERACAKE_PIN_LEDEN(x) (x<<0) -#define OPERACAKE_PA1 (0) -#define OPERACAKE_PA2 (OPERACAKE_PIN_U2CTRL0) -#define OPERACAKE_PA3 (OPERACAKE_PIN_U2CTRL1) -#define OPERACAKE_PA4 (OPERACAKE_PIN_U2CTRL0 | OPERACAKE_PIN_U2CTRL1) +#define OPERACAKE_PORT_A1 (OPERACAKE_PIN_U2CTRL0(0) | OPERACAKE_PIN_U2CTRL1(0)) +#define OPERACAKE_PORT_A2 (OPERACAKE_PIN_U2CTRL0(1) | OPERACAKE_PIN_U2CTRL1(0)) +#define OPERACAKE_PORT_A3 (OPERACAKE_PIN_U2CTRL0(0) | OPERACAKE_PIN_U2CTRL1(1)) +#define OPERACAKE_PORT_A4 (OPERACAKE_PIN_U2CTRL0(1) | OPERACAKE_PIN_U2CTRL1(1)) -#define OPERACAKE_PB1 (0) -#define OPERACAKE_PB2 (OPERACAKE_PIN_U3CTRL0) -#define OPERACAKE_PB3 (OPERACAKE_PIN_U3CTRL1) -#define OPERACAKE_PB4 (OPERACAKE_PIN_U3CTRL0 | OPERACAKE_PIN_U3CTRL1) +#define OPERACAKE_PORT_B1 (OPERACAKE_PIN_U3CTRL0(0) | OPERACAKE_PIN_U3CTRL1(0)) +#define OPERACAKE_PORT_B2 (OPERACAKE_PIN_U3CTRL0(1) | OPERACAKE_PIN_U3CTRL1(0)) +#define OPERACAKE_PORT_B3 (OPERACAKE_PIN_U3CTRL0(0) | OPERACAKE_PIN_U3CTRL1(1)) +#define OPERACAKE_PORT_B4 (OPERACAKE_PIN_U3CTRL0(1) | OPERACAKE_PIN_U3CTRL1(1)) -#define OPERACAKE_CROSSOVER (0) -#define OPERACAKE_EN_LEDS (OPERACAKE_PIN_LEDEN2) +#define OPERACAKE_SAMESIDE OPERACAKE_PIN_U1CTRL(1) +#define OPERACAKE_CROSSOVER OPERACAKE_PIN_U1CTRL(0) +#define OPERACAKE_EN_LEDS (OPERACAKE_PIN_LEDEN2(1) | OPERACAKE_PIN_LEDEN2(0)) +#define OPERACAKE_GPIO_EN OPERACAKE_PIN_OE(0) +#define OPERACAKE_GPIO_DISABLE OPERACAKE_PIN_OE(1) #define OPERACAKE_REG_INPUT 0x00 #define OPERACAKE_REG_OUTPUT 0x01 #define OPERACAKE_REG_POLARITY 0x02 #define OPERACAKE_REG_CONFIG 0x03 -#define OPERACAKE_DEFAULT_OUTPUT (OPERACAKE_PIN_OE | OPERACAKE_PIN_U1CTRL | \ - OPERACAKE_PA1 | OPERACAKE_PB1 | \ - OPERACAKE_EN_LEDS) +#define OPERACAKE_DEFAULT_OUTPUT (OPERACAKE_GPIO_DISABLE | OPERACAKE_SAMESIDE \ + | OPERACAKE_PORT_A1 | OPERACAKE_PORT_B1 \ + | OPERACAKE_EN_LEDS) #define OPERACAKE_CONFIG_ALL_OUTPUT (0x00) typedef struct { @@ -79,16 +82,58 @@ uint8_t operacake_init(void) { return 0; } -uint8_t operacake_set_ports(uint8_t PA, uint8_t PB) { - return PA | PB; +uint8_t port_to_pins(uint8_t port) { + switch(port) { + case OPERACAKE_PA1: + return OPERACAKE_PORT_A1; + case OPERACAKE_PA2: + return OPERACAKE_PORT_A2; + case OPERACAKE_PA3: + return OPERACAKE_PORT_A3; + case OPERACAKE_PA4: + return OPERACAKE_PORT_A4; + + case OPERACAKE_PB1: + return OPERACAKE_PORT_B1; + case OPERACAKE_PB2: + return OPERACAKE_PORT_B2; + case OPERACAKE_PB3: + return OPERACAKE_PORT_B3; + case OPERACAKE_PB4: + return OPERACAKE_PORT_B4; + } + return 0xFF; } -/* read single register */ -uint8_t operacake_read_single(operacake_driver_t* drv, uint8_t reg) { - const uint8_t data_tx[] = { reg }; - uint8_t data_rx[] = { 0x00 }; - i2c_bus_transfer(drv->bus, drv->i2c_address, data_tx, 1, data_rx, 1); - return data_rx[0]; +uint8_t operacake_set_ports(uint8_t PA, uint8_t PB) { + uint8_t side, pa, pb; + uint8_t output_data[2]; + /* Start with some error checking, + * which should have been done either + * on the host or elsewhere in firmware + */ + if((PA > OPERACAKE_PB4) || (PB > OPERACAKE_PB4)) { + return 1; + } + /* Check which side PA and PB are on */ + if(((PA <= OPERACAKE_PA4) && (PB <= OPERACAKE_PA4)) + || ((PA > OPERACAKE_PA4) && (PB > OPERACAKE_PA4))) { + return 1; + } + + if(PA > OPERACAKE_PA4) + side = OPERACAKE_CROSSOVER; + else + side = OPERACAKE_SAMESIDE; + + pa = port_to_pins(PA); + pb = port_to_pins(PB); + + output_data[0] = OPERACAKE_REG_OUTPUT; + output_data[1] = (OPERACAKE_GPIO_DISABLE | side + | pa | pb | OPERACAKE_EN_LEDS); + operacake_write(&operacake_driver, output_data, 2); + return 0; } /* Write to one of the PCA9557 registers */ diff --git a/firmware/common/operacake.h b/firmware/common/operacake.h index 33c35a4f..20a9a998 100644 --- a/firmware/common/operacake.h +++ b/firmware/common/operacake.h @@ -30,6 +30,16 @@ extern "C" #include #include "i2c_bus.h" +#define OPERACAKE_PA1 0 +#define OPERACAKE_PA2 1 +#define OPERACAKE_PA3 2 +#define OPERACAKE_PA4 3 + +#define OPERACAKE_PB1 4 +#define OPERACAKE_PB2 5 +#define OPERACAKE_PB3 6 +#define OPERACAKE_PB4 7 + uint8_t operacake_init(void); uint8_t operacake_set_ports(uint8_t PA, uint8_t PB); diff --git a/firmware/hackrf_usb/usb_api_operacake.c b/firmware/hackrf_usb/usb_api_operacake.c index 7ac4da81..c93ec494 100644 --- a/firmware/hackrf_usb/usb_api_operacake.c +++ b/firmware/hackrf_usb/usb_api_operacake.c @@ -22,15 +22,13 @@ #include "usb_api_operacake.h" #include "usb_queue.h" -#include -#include #include usb_request_status_t usb_vendor_request_operacake_set_ports( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage) { if (stage == USB_TRANSFER_STAGE_SETUP) { - /* TODO: implement something */ + operacake_set_ports(endpoint->setup.index, endpoint->setup.value); usb_transfer_schedule_ack(endpoint->in); } return USB_REQUEST_STATUS_OK;