fw: power, fpga handling, fix ptn3460 params

This commit is contained in:
Wenting Zhang 2023-03-04 12:34:53 -05:00
parent 40d2564772
commit eb59d7f209
14 changed files with 42690 additions and 12 deletions

View file

@ -25,6 +25,10 @@ add_executable(fw
fusb302.c fusb302.c
ptn3460.c ptn3460.c
tcpm_driver.c tcpm_driver.c
tps65185.c
max17135.c
bitstream.c
fpga.c
usb_pd_driver.c usb_pd_driver.c
usb_pd_policy.c usb_pd_policy.c
usb_pd_protocol.c usb_pd_protocol.c

42264
fw/bitstream.c Normal file

File diff suppressed because it is too large Load diff

25
fw/bitstream.h Normal file
View file

@ -0,0 +1,25 @@
//
// Copyright 2022 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#pragma once
extern const char fpga_bitstream[];
extern const int fpga_bitstream_length;

15
fw/edid.h Normal file
View file

@ -0,0 +1,15 @@
const char edid[129] = {
0x00,
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x6a, 0x12, 0x01,
0x00, 0x42, 0x4b, 0x1d, 0x00, 0x01, 0x20, 0x01, 0x03, 0x81, 0x1b,
0x14, 0x78, 0x06, 0xee, 0x95, 0xa3, 0x54, 0x4c, 0x99, 0x26, 0x0f,
0x50, 0x54, 0x00, 0x00, 0x00, 0xa9, 0x40, 0x01, 0x00, 0x01, 0x00,
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x48,
0x3f, 0x40, 0x30, 0x62, 0xb0, 0x32, 0x40, 0x40, 0xc0, 0x13, 0x00,
0x10, 0xcb, 0x10, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0xfc, 0x00,
0x50, 0x61, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x6f, 0x6e, 0x69, 0x74,
0x6f, 0x72, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x0a, 0x20, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00,
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b
};

106
fw/fpga.c Normal file
View file

@ -0,0 +1,106 @@
//
// Copyright 2022 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "pico/stdlib.h"
#include "fpga.h"
#include "bitstream.h"
#define FPGA_CS 12
#define FPGA_MOSI 13
#define FPGA_MISO 14
#define FPGA_SCLK 15
#define FPGA_PROG 17
#define FPGA_DONE 18
#define FPGA_SUSP 19
static int fpga_done = 0;
static void gpio_init_out(uint32_t pin, bool val) {
gpio_init(pin);
gpio_put(pin, val);
gpio_set_dir(pin, GPIO_OUT);
}
static void gpio_init_ipu(uint32_t pin) {
gpio_init(pin);
gpio_pull_up(pin);
}
static void delay_loop(uint32_t t) {
volatile uint32_t x = t;
while (x--);
}
static void fpga_send_byte(uint8_t byte) {
for (int i = 0; i < 8; i++) {
gpio_put(FPGA_MOSI, byte & 0x80);
gpio_put(FPGA_SCLK, 1);
byte <<= 1;
gpio_put(FPGA_SCLK, 0);
}
}
static void fpga_load_bitstream(uint8_t *stream, int size) {
gpio_put(FPGA_CS, 0);
for (int i = 0; i < size; i++) {
fpga_send_byte(stream[i]);
}
gpio_put(FPGA_CS, 1);
for (int i = 0; i < 1000; i++) {
if (gpio_get(FPGA_DONE) == 1)
break;
sleep_ms(1);
}
if (gpio_get(FPGA_DONE) == 0) {
fatal("FPGA done does not go high after 1s");
}
else {
printf("FPGA bitstream load done.");
}
}
void fpga_init(void) {
// Initialize FPGA pins
gpio_init_out(FPGA_CS, 1);
gpio_init_out(FPGA_MOSI, 1);
gpio_init_ipu(FPGA_MISO);
gpio_init_out(FPGA_SCLK, 0);
gpio_init_out(FPGA_PROG, 1);
gpio_init_ipu(FPGA_DONE);
gpio_init_out(FPGA_SUSP, 0);
// FPGA Reset
gpio_put(FPGA_PROG, 0);
sleep_ms(100);
gpio_put(FPGA_PROG, 1);
sleep_ms(100);
// Load bitstream
fpga_load_bitstream(fpga_bitstream, fpga_bitstream_length);
}
void fpga_suspend(void) {
}
void fpga_resume(void) {
}

26
fw/fpga.h Normal file
View file

@ -0,0 +1,26 @@
//
// Copyright 2022 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#pragma once
void fpga_init(void);
void fpga_suspend(void);
void fpga_resume(void);

20
fw/fw.c
View file

@ -27,12 +27,18 @@
#include "tcpm_driver.h" #include "tcpm_driver.h"
#include "usb_pd.h" #include "usb_pd.h"
#include "ptn3460.h" #include "ptn3460.h"
#include "tps65185.h"
#include "max17135.h"
#include "fpga.h"
int main() int main()
{ {
stdio_init_all(); stdio_init_all();
sleep_ms(1000); //sleep_ms(2000);
printf("\n");
printf("Glider\n");
int result = tcpm_init(0); int result = tcpm_init(0);
if (result) if (result)
@ -42,12 +48,20 @@ int main()
tcpc_config[0].drv->get_cc(0, &cc1, &cc2); tcpc_config[0].drv->get_cc(0, &cc1, &cc2);
printf("CC status %d %d\n", cc1, cc2); printf("CC status %d %d\n", cc1, cc2);
gpio_init(10);
gpio_put(10, 0);
gpio_set_dir(10, GPIO_OUT);
tps_init();
fpga_init();
ptn3460_init(); ptn3460_init();
pd_init(0); pd_init(0);
sleep_ms(50); sleep_ms(50);
extern int dp_enabled; extern int dp_enabled;
bool hpd_sent = false; bool hpd_sent = false;
bool dp_valid = false;
while (1) { while (1) {
// TODO: Implement interrupt // TODO: Implement interrupt
@ -58,6 +72,10 @@ int main()
pd_send_hpd(0, hpd_high); pd_send_hpd(0, hpd_high);
hpd_sent = true; hpd_sent = true;
} }
if (dp_valid != ptn3460_is_valid()) {
dp_valid = ptn3460_is_valid();
printf(dp_valid ? "Input is valid\n" : "Input is invalid\n");
}
} }
return 0; return 0;

72
fw/max17135.c Normal file
View file

@ -0,0 +1,72 @@
//
// Copyright 2022 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "max17135.h"
#define MAX_I2C i2c0
#define MAX_I2C_ADDR 0x48
void max_write(uint8_t reg, uint8_t val) {
uint8_t buf[2];
int result;
buf[0] = reg;
buf[1] = val;
result = i2c_write_blocking(MAX_I2C, MAX_I2C_ADDR, buf, 2, false);
if (result != 2) {
fatal("Failed writing data to MAX");
}
}
uint8_t max_read(uint8_t reg) {
int result;
uint8_t buf[1];
buf[0] = reg;
result = i2c_write_blocking(MAX_I2C, MAX_I2C_ADDR, buf, 1, true);
if (result != 1) {
fatal("Failed writing data to MAX");
}
result = i2c_read_blocking(MAX_I2C, MAX_I2C_ADDR, buf, 1, false);
if (result != 1) {
fatal("Failed reading data from MAX");
}
return buf[0];
}
void max_set_vcom(uint16_t vcom) {
max_write(0x04, (vcom >> 16));
max_write(0x03, vcom & 0xff);
}
void max_init(void) {
//max_set_vcom(100); // -1V
printf("Product Revision: %08x\n", max_read(0x06));
printf("Product ID: %08x\n", max_read(0x07));
max_write(0x10, 0x80);
max_write(0x09, 0x01); // Startup
for (int i = 0; i < 20; i++) {
sleep_ms(10);
uint8_t val = max_read(0x05);
printf("Status: %08x\n", val);
}
printf("Fault: %08x\n", max_read(0x0a));
}

24
fw/max17135.h Normal file
View file

@ -0,0 +1,24 @@
//
// Copyright 2022 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#pragma once
void tps_init(void);

View file

@ -24,12 +24,13 @@
#include "hardware/i2c.h" #include "hardware/i2c.h"
#include "ptn3460.h" #include "ptn3460.h"
#include "utils.h" #include "utils.h"
//#include "edid.h" #include "edid.h"
#define PTN3460_I2C_ADDRESS (0x60) #define PTN3460_I2C_ADDRESS (0x60)
#define PTN3460_I2C (i2c0) #define PTN3460_I2C (i2c0)
#define PTN3460_HPD_PIN (8) #define PTN3460_HPD_PIN (8)
#define PTN3460_PDN_PIN (9) #define PTN3460_PDN_PIN (9)
#define PTN3460_VALID_PIN (2)
void ptn3460_select_edid_emulation(uint8_t id) { void ptn3460_select_edid_emulation(uint8_t id) {
uint8_t buf[2]; uint8_t buf[2];
@ -44,14 +45,22 @@ void ptn3460_select_edid_emulation(uint8_t id) {
} }
void ptn3460_load_edid(uint8_t *edid) { void ptn3460_load_edid(uint8_t *edid) {
uint8_t buf[1];
int result; int result;
buf[0] = 0;
result = i2c_write_blocking(PTN3460_I2C, PTN3460_I2C_ADDRESS, result = i2c_write_blocking(PTN3460_I2C, PTN3460_I2C_ADDRESS,
buf, 1, true); edid, 129, false);
if (result != 129) {
fatal("Failed writing data to PTN3460\n");
}
}
void ptn3460_write(uint8_t reg, uint8_t val) {
uint8_t buf[2];
int result;
buf[0] = reg;
buf[1] = val;
result = i2c_write_blocking(PTN3460_I2C, PTN3460_I2C_ADDRESS, result = i2c_write_blocking(PTN3460_I2C, PTN3460_I2C_ADDRESS,
edid, 128, false); buf, 2, false);
if (result != 128) { if (result != 2) {
fatal("Failed writing data to PTN3460\n"); fatal("Failed writing data to PTN3460\n");
} }
} }
@ -63,6 +72,9 @@ void ptn3460_init() {
gpio_init(PTN3460_PDN_PIN); gpio_init(PTN3460_PDN_PIN);
gpio_put(PTN3460_PDN_PIN, 1); gpio_put(PTN3460_PDN_PIN, 1);
gpio_set_dir(PTN3460_PDN_PIN, GPIO_OUT); gpio_set_dir(PTN3460_PDN_PIN, GPIO_OUT);
gpio_init(PTN3460_VALID_PIN);
gpio_set_dir(PTN3460_VALID_PIN, GPIO_IN);
gpio_pull_down(PTN3460_VALID_PIN);
sleep_ms(100); sleep_ms(100);
// wait for HPD to become high // wait for HPD to become high
int ticks = 0; int ticks = 0;
@ -76,9 +88,12 @@ void ptn3460_init() {
printf("PTN3460 up after %d ms\n", ticks); printf("PTN3460 up after %d ms\n", ticks);
// Enable EDID emulation // Enable EDID emulation
ptn3460_select_edid_emulation(0); ptn3460_select_edid_emulation(0);
//ptn3460_load_edid(); ptn3460_load_edid(edid);
uint8_t buf[2]; //ptn3460_write(0x80, 0x02); // Set AUX reverse
ptn3460_write(0x81, 0x29); // 18bpp, clock on odd bus, dual channel
/*uint8_t buf[2];
int result; int result;
buf[0] = (uint8_t)0x80; buf[0] = (uint8_t)0x80;
buf[1] = (uint8_t)0x02; buf[1] = (uint8_t)0x02;
@ -86,5 +101,9 @@ void ptn3460_init() {
buf, 2, false); buf, 2, false);
if (result != 2) { if (result != 2) {
fatal("Failed writing data to PTN3460\n"); fatal("Failed writing data to PTN3460\n");
}*/
} }
bool ptn3460_is_valid() {
return gpio_get(PTN3460_VALID_PIN);
} }

View file

@ -22,3 +22,4 @@
#pragma once #pragma once
void ptn3460_init(); void ptn3460_init();
bool ptn3460_is_valid();

79
fw/tps65185.c Normal file
View file

@ -0,0 +1,79 @@
//
// Copyright 2022 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#include "pico/stdlib.h"
#include "hardware/i2c.h"
#include "tps65185.h"
#define TPS_I2C i2c0
#define TPS_I2C_ADDR 0x68
//#define TPS_I2C_ADDR 0x34
#define TPS_EN_PIN 21
void tps_write(uint8_t reg, uint8_t val) {
uint8_t buf[2];
int result;
buf[0] = reg;
buf[1] = val;
result = i2c_write_blocking(TPS_I2C, TPS_I2C_ADDR, buf, 2, false);
if (result != 2) {
fatal("Failed writing data to TPS");
}
}
uint8_t tps_read(uint8_t reg) {
int result;
uint8_t buf[1];
buf[0] = reg;
result = i2c_write_blocking(TPS_I2C, TPS_I2C_ADDR, buf, 1, true);
if (result != 1) {
fatal("Failed writing data to TPS");
}
result = i2c_read_blocking(TPS_I2C, TPS_I2C_ADDR, buf, 1, false);
if (result != 1) {
fatal("Failed reading data from TPS");
}
return buf[0];
}
void tps_set_vcom(uint16_t vcom) {
tps_write(0x04, (vcom >> 16));
tps_write(0x03, vcom & 0xff);
}
void tps_init(void) {
gpio_init(TPS_EN_PIN);
gpio_put(TPS_EN_PIN, 1);
gpio_set_dir(TPS_EN_PIN, GPIO_OUT);
for (int i = 0; i < 100; i++) {
sleep_ms(5);
uint8_t val = tps_read(0x0f);
printf("Val: %08x\n", val);
}
sleep_ms(1000);
tps_set_vcom(212); // -1V
printf("VADJ: %08x\n", tps_read(0x02));
printf("UPSEQ0: %08x\n", tps_read(0x09));
printf("UPSEQ1: %08x\n", tps_read(0x0a));
printf("INT1: %08x\n", tps_read(0x07));
printf("INT2: %08x\n", tps_read(0x08));
}

24
fw/tps65185.h Normal file
View file

@ -0,0 +1,24 @@
//
// Copyright 2022 Wenting Zhang <zephray@outlook.com>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
#pragma once
void tps_init(void);

View file

@ -32,6 +32,7 @@ void fatal(const char *msg, ...) {
printf("[FATAL] "); printf("[FATAL] ");
vprintf(msg, params); vprintf(msg, params);
printf("\n");
va_end(params); va_end(params);