controller/Src/io.c

233 lines
6.9 KiB
C

#include "io.h"
// @todo We should probably add DATA_0... as defines
#define CLOCK_PIN GPIO_PIN_11
#define CLOCK_PORT GPIOB
#define RESET_PIN GPIO_PIN_3
#define RESET_PORT GPIOE
/* #define ADDRESS_PORT GPIOD */
GPIO_TypeDef* ADDRESS_PORT[] = {GPIOD, GPIOD, GPIOD, GPIOD, GPIOB, GPIOB, GPIOB, GPIOB,
GPIOB, GPIOE, GPIOE, GPIOA, GPIOA, GPIOD, GPIOD, GPIOD};
const uint16_t ADDRESS_PIN[] = {GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_6, GPIO_PIN_7, GPIO_PIN_3, GPIO_PIN_4, GPIO_PIN_5, GPIO_PIN_8,
GPIO_PIN_9, GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_14, GPIO_PIN_15, GPIO_PIN_0, GPIO_PIN_1, GPIO_PIN_3};
GPIO_TypeDef* DATA_PORT[] = {GPIOD, GPIOD, GPIOD, GPIOD, GPIOC, GPIOC, GPIOA, GPIOA};
const uint16_t DATA_PIN[] = {GPIO_PIN_12, GPIO_PIN_13, GPIO_PIN_14, GPIO_PIN_15, GPIO_PIN_6, GPIO_PIN_7, GPIO_PIN_9, GPIO_PIN_10};
GPIO_TypeDef* DEV_SELECT_PORT[] = {GPIOD, GPIOD, GPIOD, GPIOD, GPIOB, GPIOB, GPIOB, GPIOB};
const uint16_t DEV_SELECT_PIN[] = {GPIO_PIN_11, GPIO_PIN_10, GPIO_PIN_9, GPIO_PIN_8, GPIO_PIN_15, GPIO_PIN_14, GPIO_PIN_13, GPIO_PIN_12};
#define READ_PIN GPIO_PIN_0
#define READ_PORT GPIOC
#define WRITE_PIN GPIO_PIN_13
#define WRITE_PORT GPIOC
#define MEMORY_REQUEST_PIN GPIO_PIN_0
#define MEMORY_REQUEST_PORT GPIOA
#define IO_REQUEST_PIN GPIO_PIN_1
#define IO_REQUEST_PORT GPIOA
#define M1_PIN GPIO_PIN_2
#define M1_PORT GPIOE
#define BUSRQ_PORT GPIOE
#define BUSRQ_PIN GPIO_PIN_4
#define BUSAK_PORT GPIOE
#define BUSAK_PIN GPIO_PIN_6
#define INT_PORT GPIOC
#define INT_PIN GPIO_PIN_1
uint16_t read_address() {
uint16_t address = 0;
address |= (GPIOD->IDR & (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7)) >> 4;
address |= (GPIOB->IDR & (GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5)) << 1;
address |= (GPIOB->IDR & (GPIO_PIN_8 | GPIO_PIN_9)) >> 1;
address |= (GPIOE->IDR & (GPIO_PIN_0 | GPIO_PIN_1)) << 9;
address |= (GPIOA->IDR & (GPIO_PIN_14 | GPIO_PIN_15)) >> 3;
address |= (GPIOD->IDR & (GPIO_PIN_0 | GPIO_PIN_1)) << 13;
address |= (GPIOD->IDR & GPIO_PIN_3) << 12;
return address;
}
void write_address(uint16_t address) {
for (int i = 0; i < 16; ++i) {
HAL_GPIO_WritePin(ADDRESS_PORT[i], ADDRESS_PIN[i], address & (1 << i) ? GPIO_PIN_SET : GPIO_PIN_RESET);
}
}
void enable_address_out(uint8_t enable) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
for (int i = 0; i < 16; ++i) {
GPIO_InitStruct.Pin = ADDRESS_PIN[i];
GPIO_InitStruct.Mode = enable ? GPIO_MODE_OUTPUT_PP : GPIO_MODE_INPUT;
HAL_GPIO_Init(ADDRESS_PORT[i], &GPIO_InitStruct);
}
}
uint8_t read_data() {
uint16_t data = 0;
data |= (GPIOD->IDR & (GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)) >> 12;
data |= (GPIOC->IDR & (GPIO_PIN_6 | GPIO_PIN_7)) >> 2;
data |= (GPIOA->IDR & (GPIO_PIN_9 | GPIO_PIN_10)) >> 3;
return data;
}
void write_data(uint8_t value) {
GPIOD->BSRR= ((value & 0xF) | ((~value & 0xF) << 16)) << 12;
GPIOC->BSRR= ((value & 0x30) | ((~value & 0x30) << 16)) << 2;
GPIOA->BSRR = ((value & 0xC0) | ((~value & 0xC0) << 16)) << 3;
}
void enable_data_out(uint8_t enable) {
static uint8_t cur = 2;
if (cur != enable) {
cur = enable;
if (enable) {
GPIOD->MODER |= (GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 | GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0);
GPIOC->MODER |= (GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0);
GPIOA->MODER |= (GPIO_MODER_MODER9_0 | GPIO_MODER_MODER10_0);
} else {
// @todo We can optimze this in a similair manner as above
GPIOD->MODER &= ~(GPIO_MODER_MODER12);
GPIOD->MODER &= ~(GPIO_MODER_MODER13);
GPIOD->MODER &= ~(GPIO_MODER_MODER14);
GPIOD->MODER &= ~(GPIO_MODER_MODER15);
GPIOC->MODER &= ~(GPIO_MODER_MODER6);
GPIOC->MODER &= ~(GPIO_MODER_MODER7);
GPIOA->MODER &= ~(GPIO_MODER_MODER9);
GPIOA->MODER &= ~(GPIO_MODER_MODER10);
}
}
}
void select_device(uint8_t device) {
static uint8_t cur = 0xFF;
if (cur != device) {
cur = device;
GPIOB->BSRR = ((device & 0xF) | ((~device & 0xF) << 16)) << 12;
GPIOD->BSRR = ((device & 0xF0) | ((~device & 0xF0) << 16)) << 4;
}
}
void set_reset(uint8_t high) {
GPIOE->BSRR = ((~high & 1) | ((high & 1) << 16)) << 3;
}
void set_clock(uint8_t high) {
GPIOB->BSRR = ((high & 1) | ((~high & 1) << 16)) << 11;
}
uint8_t has_memrq() {
return !(MEMORY_REQUEST_PORT->IDR & MEMORY_REQUEST_PIN);
}
void send_memrq(uint8_t high) {
HAL_GPIO_WritePin(MEMORY_REQUEST_PORT, MEMORY_REQUEST_PIN, high ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
void enable_memrq_out(uint8_t enable) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = MEMORY_REQUEST_PIN;
GPIO_InitStruct.Mode = enable ? GPIO_MODE_OUTPUT_PP : GPIO_MODE_INPUT;
HAL_GPIO_Init(MEMORY_REQUEST_PORT, &GPIO_InitStruct);
}
uint8_t has_ioreq() {
return !(IO_REQUEST_PORT->IDR & IO_REQUEST_PIN);
}
uint8_t has_m1() {
return !(M1_PORT->IDR & M1_PIN);
}
uint8_t has_rd() {
return !(READ_PORT->IDR & READ_PIN);
}
void send_rd(uint8_t high) {
HAL_GPIO_WritePin(READ_PORT, READ_PIN, high ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
void enable_rd_out(uint8_t enable) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = READ_PIN;
GPIO_InitStruct.Mode = enable ? GPIO_MODE_OUTPUT_PP : GPIO_MODE_INPUT;
HAL_GPIO_Init(READ_PORT, &GPIO_InitStruct);
}
uint8_t has_wr() {
return !(WRITE_PORT->IDR & WRITE_PIN);
}
void send_wr(uint8_t high) {
HAL_GPIO_WritePin(WRITE_PORT, WRITE_PIN, high ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
void enable_wr_out(uint8_t enable) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = WRITE_PIN;
GPIO_InitStruct.Mode = enable ? GPIO_MODE_OUTPUT_PP : GPIO_MODE_INPUT;
HAL_GPIO_Init(WRITE_PORT, &GPIO_InitStruct);
}
uint8_t has_busak() {
return !(BUSAK_PORT->IDR & BUSAK_PIN);
}
void send_busrq(uint8_t control) {
if (control) {
// Set correct defaults
send_memrq(0);
send_wr(0);
send_rd(0);
}
// @todo This should not happen unitl busak
enable_memrq_out(control);
enable_rd_out(control);
enable_wr_out(control);
enable_address_out(control);
HAL_GPIO_WritePin(BUSRQ_PORT, BUSRQ_PIN, control ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
void send_int(uint8_t control) {
static uint8_t cur = 2;
if (cur != control) {
cur = control;
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Pin = INT_PIN;
GPIO_InitStruct.Mode = control ? GPIO_MODE_OUTPUT_PP : GPIO_MODE_INPUT;
HAL_GPIO_Init(INT_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(INT_PORT, INT_PIN, control ? GPIO_PIN_RESET : GPIO_PIN_SET);
}
}