Files
OpenCellular/chip/g/uart_bitbang.h
Randall Spangler a285acd36f cr50: Consolidate CCD device enable
Currently, the Cr50 state machines (EC, AP, RDD, bitbang, etc.) manage
their own enabling and disabling of the ports (UART, SPI, etc.)  This
is tricky because the rules for when ports should be enabled are
non-trivial and must be applied in the correct order.  In additionl
the changes all need to be serialized, so that the hardware ends up in
the correct state even if multiple state machines are changing
simultaneously.

Consolidate all of that into chip/g/rdd.c.  The debug command for it
is now 'ccdstate', which just prints the state machines.  This will
allow subsequent renaming of the 'ccdopen', etc. commands to 'ccd
open', etc.

Also include UART bit-banging into that state which must be
consistent.  Previously, it was possible for bit-banging to leave UART
TX connected, instead of returning it to the previous state.

Use better names for CCD config fields for UART.  I'd had them backwards.

BUG=b:62537474
BRANCH=cr50
TEST=manual, with a CR50_DEV=1 image
	1) No servo or CCD
	Pull SERVO_DETECT low (disconnected)
	Pull CCD_MODE_L high (disabled)
	Pull EC_DETECT and AP_DETECT high (on)
	Reboot.  RX is enabled even if cables are disconnected so we buffer.
	ccdstate -> UARTAP UARTEC

	Pull EC_DETECT low.
	ccdstate -> UARTAP

	Pull EC_DETECT high and AP_DETECT low.
	ccdstate -> UARTEC
	Pull AP_DETECT high.
	ccdstate -> UARTAP UARTEC

	2) Servo only still allows UART RX
	Pull SERVO_DETECT high (connected).
	ccdstate -> UARTAP UARTEC

	3) Both servo and CCD prioritizes servo.
	Pull CCD_MODE_L low (enabled).
	ccdstate -> UARTAP UARTEC

	Reboot, to make sure servo wins at boot time.
	ccdstate -> UARTAP UARTEC

	Bit-banging doesn't work when servo is connected.
	bitbang 2 9600 even -> superseded by servo
	bitbang -> disabled
	ccdstate -> UARTAP UARTEC

	4) CCD only allows more ports and remembers we wanted to bit-bang
	Pull SERVO_DETECT low.
	ccdstate --> UARTAP+TX UARTEC+BB I2C SPI
	bitbang 2 disable
	ccdstate --> UARTAP+TX UARTEC+TX I2C SPI

	Reboot and see we don't take over servo ports until we're
	sure servo isn't present.
	ccdstate --> UARTAP UARTEC (for first second)
	ccdstate --> UARTAP+TX UARTEC+TX I2C SPI (after that)

	5) Bit-banging takes over ECTX
	bitbang 2 9600 even
	bitbang -> baud rate 9600, parity even
	ccdstate -> UARTAP+TX UARTEC+BB I2C SPI

	bitbang 2 disable
	ccdstate -> UARTAP+TX UARTEC+TX I2C SPI

	6) Permissions work.  Allow easy access to full console and ccdopen:
	ccdset OpenNoTPMWipe always
	ccdset OpenNoLongPP always
	ccdset GscFullConsole always

	Default when locked is full AP UART EC RO, no I2C or SPI
	ccdlock
	ccdstate -> UARTAP+TX UARTEC

	No EC transmit permission means no bit-banging
	bitbang 2 9600 even
	bitbang -> disabled
	ccdstate -> UARTAP+TX UARTEC

	But it remembers that we wanted to
	ccdopen
	ccdstate -> UARTAP+TX UARTEC+BB I2C SPI
	bitbang 2 disable
	ccdstate -> UARTAP+TX UARTEC+TX I2C SPI

	Try turning on/off permissions
	ccdset UartGscTxECRx always
	ccdlock
	ccdstate -> UARTAP+TX UARTEC+TX

	No read means no write either
	ccdset UartGscRxECTx ifopened
	ccdlock
	ccdstate -> UARTAP+TX
	ccdopen
	ccdset UartGscRXAPTx ifopened
	ccdlock
	ccdstate -> (nothing)

	Check AP transmit permissions too
	ccdopen
	ccdset UartGscRxAPTx always
	ccdset UartGscTxAPRx ifopened
	ccdlock
	ccdstate -> UARTAP

	Check I2C
	ccdopen
	ccdset I2C always
	ccdlock
	ccdstate -> UARTAP I2C

	SPI port is enabled if either EC or AP flash is allowed
	ccdopen
	ccdset flashap always
	ccdlock
	ccdstate -> UARTAP I2C SPI
	ccdopen
	ccdset flashec always
	ccdset flashap ifopened
	ccdlock
	ccdstate -> UARTAP I2C SPI

	Back to defaults
	ccdoops

Change-Id: I641f7ab2354570812e3fb37b470de32e5bd10db7
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/615928
Reviewed-by: Mary Ruthven <mruthven@chromium.org>
2017-09-06 19:12:57 -07:00

131 lines
3.4 KiB
C

/* Copyright 2017 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef __CROS_EC_CHIP_G_UART_BITBANG_H
#define __CROS_EC_CHIP_G_UART_BITBANG_H
/* UART Bit Banging */
#include "common.h"
#include "gpio.h"
/* These are functions that we'll have to replace. */
struct uartn_function_ptrs {
int (*_rx_available)(int uart);
void (*_write_char)(int uart, char c);
int (*_read_char)(int uart);
};
/*
* And these are the function definitions. The functions live in
* chip/g/uartn.c.
*/
extern int _uartn_rx_available(int uart);
extern void _uartn_write_char(int uart, char c);
extern int _uartn_read_char(int uart);
extern int _uart_bitbang_rx_available(int uart);
extern void _uart_bitbang_write_char(int uart, char c);
extern int _uart_bitbang_read_char(int uart);
extern struct uartn_function_ptrs uartn_funcs[];
struct uart_bitbang_properties {
enum gpio_signal tx_gpio;
enum gpio_signal rx_gpio;
uint32_t tx_pinmux_reg;
uint32_t tx_pinmux_regval;
uint32_t rx_pinmux_reg;
uint32_t rx_pinmux_regval;
int baud_rate;
uint8_t uart;
struct {
unsigned int head : 3;
unsigned int tail : 3;
unsigned int parity : 2;
} htp __packed;
};
/* In order to bitbang a UART, a board must define a bitbang_config. */
extern struct uart_bitbang_properties bitbang_config;
/**
* Configure bit banging mode for a UART.
*
* If configuration succeeds, then call uart_bitbang_enable() on the port.
*
* @param uart: Index of UART to enable bit banging mode.
* @param baud_rate: desired baud rate.
* @param parity: 0: no parity, 1: odd parity, 2: even parity.
*
* @returns EC_SUCCESS on success, otherwise an error.
*/
int uart_bitbang_config(int uart, int baud_rate, int parity);
/**
* Enable bit banging mode for a UART.
*
* The UART must have been configured first.
*
* @param uart: Index of UART to disable bit banging mode.
*/
int uart_bitbang_enable(int uart);
/**
* Disable bit banging mode for a UART.
*
* @param uart: Index of UART to disable bit banging mode.
*/
int uart_bitbang_disable(int uart);
/**
* Returns 1 if bit banging mode is enabled for the UART.
*
* @param uart: Index of UART to query.
*/
int uart_bitbang_is_enabled(int uart);
/**
* Returns 1 if bit banging mode is wanted for the UART.
*
* @param uart: Index of UART to query.
*/
int uart_bitbang_is_wanted(int uart);
/**
* TX a character on a UART configured for bit banging mode.
*
* @param uart: Index of UART to use.
* @param c: Character to send out.
*/
void uart_bitbang_write_char(int uart, char c);
/**
* Sample the RX line on a UART configured for bit banging mode.
*
* This is called when a falling edge is seen on the RX line and will attempt to
* receive a character. Incoming data with framing errors or parity errors will
* be discarded.
*
* @param uart: Index of UART to use.
* @returns EC_SUCCESS if a character was successfully received, EC_ERROR_CRC if
* there was a framing or parity issue.
*/
int uart_bitbang_receive_char(int uart);
/**
* Returns 1 if there are characters available for consumption, otherwise 0.
*
* @param uart: Index of UART to check.
*/
int uart_bitbang_is_char_available(int uart);
/**
* Retrieve a character from the bit bang RX buffer.
*
* @param uart: Index of UART to use.
*/
int uart_bitbang_read_char(int uart);
#endif /* __CROS_EC_CHIP_G_UART_BITBANG_H */