Add Operacake USB API (firmware)

This commit is contained in:
Dominic Spill
2016-12-19 21:50:29 -07:00
parent bd1111a2e3
commit 1cec9ad4db
3 changed files with 85 additions and 32 deletions

View File

@ -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 */

View File

@ -30,6 +30,16 @@ extern "C"
#include <stdint.h>
#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);

View File

@ -22,15 +22,13 @@
#include "usb_api_operacake.h"
#include "usb_queue.h"
#include <stddef.h>
#include <hackrf_core.h>
#include <operacake.h>
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;