mirror of
https://github.com/solderparty/i2c_puppet.git
synced 2025-08-14 23:42:23 +02:00
Improvements commited 2 months later (I really should leave notes for myself)
This commit is contained in:
130
app/puppet_i2c.c
130
app/puppet_i2c.c
@ -1,19 +1,11 @@
|
||||
#include "puppet_i2c.h"
|
||||
|
||||
#include "app_config.h"
|
||||
#include "backlight.h"
|
||||
#include "fifo.h"
|
||||
#include "gpioexp.h"
|
||||
#include "keyboard.h"
|
||||
#include "reg.h"
|
||||
|
||||
#include <hardware/i2c.h>
|
||||
#include <hardware/irq.h>
|
||||
#include <pico/stdlib.h>
|
||||
#include <RP2040.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define WRITE_MASK (1 << 7)
|
||||
#define REG_ID_INVALID 0x00
|
||||
|
||||
static i2c_inst_t *i2c_instances[2] = { i2c0, i2c1 };
|
||||
@ -32,124 +24,6 @@ static struct
|
||||
uint8_t write_len;
|
||||
} self;
|
||||
|
||||
static void process_read(void)
|
||||
{
|
||||
const bool is_write = (self.read_buffer.reg & WRITE_MASK);
|
||||
const uint8_t reg = (self.read_buffer.reg & ~WRITE_MASK);
|
||||
|
||||
// printf("read complete, is_write: %d, reg: 0x%02X\r\n", is_write, reg);
|
||||
|
||||
switch (reg) {
|
||||
|
||||
// common R/W registers
|
||||
case REG_ID_CFG:
|
||||
case REG_ID_INT:
|
||||
case REG_ID_DEB:
|
||||
case REG_ID_FRQ:
|
||||
case REG_ID_BKL:
|
||||
case REG_ID_BK2:
|
||||
case REG_ID_GIC:
|
||||
case REG_ID_GIN:
|
||||
case REG_ID_HLD:
|
||||
case REG_ID_ADR:
|
||||
case REG_ID_IND:
|
||||
case REG_ID_CF2:
|
||||
{
|
||||
if (is_write) {
|
||||
reg_set_value(reg, self.read_buffer.data);
|
||||
|
||||
switch (reg) {
|
||||
case REG_ID_BKL:
|
||||
case REG_ID_BK2:
|
||||
backlight_sync();
|
||||
break;
|
||||
|
||||
case REG_ID_ADR:
|
||||
puppet_i2c_sync_address();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
self.write_buffer[0] = reg_get_value(reg);
|
||||
self.write_len = sizeof(uint8_t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// special R/W registers
|
||||
case REG_ID_DIR: // gpio direction
|
||||
case REG_ID_PUE: // gpio input pull enable
|
||||
case REG_ID_PUD: // gpio input pull direction
|
||||
{
|
||||
if (is_write) {
|
||||
switch (reg) {
|
||||
case REG_ID_DIR:
|
||||
gpioexp_update_dir(self.read_buffer.data);
|
||||
break;
|
||||
case REG_ID_PUE:
|
||||
gpioexp_update_pue_pud(self.read_buffer.data, reg_get_value(REG_ID_PUD));
|
||||
break;
|
||||
case REG_ID_PUD:
|
||||
gpioexp_update_pue_pud(reg_get_value(REG_ID_PUE), self.read_buffer.data);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
self.write_buffer[0] = reg_get_value(reg);
|
||||
self.write_len = sizeof(uint8_t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case REG_ID_GIO: // gpio value
|
||||
{
|
||||
if (is_write) {
|
||||
gpioexp_set_value(self.read_buffer.data);
|
||||
} else {
|
||||
self.write_buffer[0] = gpioexp_get_value();
|
||||
self.write_len = sizeof(uint8_t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// read-only registers
|
||||
case REG_ID_TOX:
|
||||
case REG_ID_TOY:
|
||||
self.write_buffer[0] = reg_get_value(reg);
|
||||
self.write_len = sizeof(uint8_t);
|
||||
|
||||
reg_set_value(reg, 0);
|
||||
break;
|
||||
|
||||
case REG_ID_VER:
|
||||
self.write_buffer[0] = VER_VAL;
|
||||
self.write_len = sizeof(uint8_t);
|
||||
break;
|
||||
|
||||
case REG_ID_KEY:
|
||||
self.write_buffer[0] = fifo_count();
|
||||
self.write_buffer[0] |= keyboard_get_numlock() ? KEY_NUMLOCK : 0x00;
|
||||
self.write_buffer[0] |= keyboard_get_capslock() ? KEY_CAPSLOCK : 0x00;
|
||||
self.write_len = sizeof(uint8_t);
|
||||
break;
|
||||
|
||||
case REG_ID_FIF:
|
||||
{
|
||||
const struct fifo_item item = fifo_dequeue();
|
||||
|
||||
self.write_buffer[0] = (uint8_t)item.state;
|
||||
self.write_buffer[1] = (uint8_t)item.key;
|
||||
self.write_len = sizeof(uint8_t) * 2;
|
||||
break;
|
||||
}
|
||||
|
||||
case REG_ID_RST:
|
||||
NVIC_SystemReset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void irq_handler(void)
|
||||
{
|
||||
// the controller sent data
|
||||
@ -157,7 +31,7 @@ static void irq_handler(void)
|
||||
if (self.read_buffer.reg == REG_ID_INVALID) {
|
||||
self.read_buffer.reg = self.i2c->hw->data_cmd & 0xff;
|
||||
|
||||
if (self.read_buffer.reg & WRITE_MASK) {
|
||||
if (self.read_buffer.reg & PACKET_WRITE_MASK) {
|
||||
// it'sq a reg write, we need to wait for the second byte before we process
|
||||
return;
|
||||
}
|
||||
@ -165,7 +39,7 @@ static void irq_handler(void)
|
||||
self.read_buffer.data = self.i2c->hw->data_cmd & 0xff;
|
||||
}
|
||||
|
||||
process_read();
|
||||
reg_process_packet(self.read_buffer.reg, self.read_buffer.data, self.write_buffer, &self.write_len);
|
||||
|
||||
// ready for the next operation
|
||||
self.read_buffer.reg = REG_ID_INVALID;
|
||||
|
Reference in New Issue
Block a user