Добавить переносимый драйвер parallel NAND
This commit is contained in:
134
ports/stm32g474ce/parallel_nand_port_stm32g474ce.c
Normal file
134
ports/stm32g474ce/parallel_nand_port_stm32g474ce.c
Normal file
@@ -0,0 +1,134 @@
|
||||
#include "parallel_nand_port_stm32g474ce.h"
|
||||
#include "stm32g4xx_hal.h"
|
||||
|
||||
/* Пустая плата STM32G474CEU6: PB0..PB7 образуют непрерывную x8 шину. */
|
||||
#define DATA_MASK 0x00FFU
|
||||
#define CLE_PIN GPIO_PIN_0
|
||||
#define ALE_PIN GPIO_PIN_1
|
||||
#define WE_PIN GPIO_PIN_2
|
||||
#define RE_PIN GPIO_PIN_3
|
||||
#define CE_PIN GPIO_PIN_4
|
||||
#define WP_PIN GPIO_PIN_5
|
||||
#define RB_PIN GPIO_PIN_6
|
||||
|
||||
static int data_is_output;
|
||||
|
||||
static void data_input(void)
|
||||
{
|
||||
if (data_is_output) {
|
||||
GPIOB->MODER &= ~0x0000FFFFUL;
|
||||
data_is_output = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void data_output(void)
|
||||
{
|
||||
if (!data_is_output) {
|
||||
GPIOB->MODER = (GPIOB->MODER & ~0x0000FFFFUL) | 0x00005555UL;
|
||||
data_is_output = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void short_delay(void)
|
||||
{
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
__NOP(); __NOP(); __NOP(); __NOP();
|
||||
}
|
||||
|
||||
static int g474_init(void)
|
||||
{
|
||||
GPIO_InitTypeDef io;
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
io.Pin = DATA_MASK;
|
||||
io.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
io.Pull = GPIO_NOPULL;
|
||||
io.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
HAL_GPIO_Init(GPIOB, &io);
|
||||
data_is_output = 1;
|
||||
data_input();
|
||||
|
||||
/* Set inactive levels before enabling the pins as outputs. */
|
||||
GPIOA->BSRR = WE_PIN | RE_PIN | CE_PIN |
|
||||
((uint32_t)(CLE_PIN | ALE_PIN | WP_PIN) << 16);
|
||||
io.Pin = CLE_PIN | ALE_PIN | WE_PIN | RE_PIN | CE_PIN | WP_PIN;
|
||||
io.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
io.Pull = GPIO_NOPULL;
|
||||
io.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &io);
|
||||
io.Pin = RB_PIN;
|
||||
io.Mode = GPIO_MODE_INPUT;
|
||||
io.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &io);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void g474_select(void) { GPIOA->BSRR = (uint32_t)CE_PIN << 16; }
|
||||
static void g474_deselect(void) { GPIOA->BSRR = CE_PIN; }
|
||||
|
||||
static void write_cycle(pnand_octet_t value)
|
||||
{
|
||||
data_output();
|
||||
GPIOB->BSRR = (uint32_t)DATA_MASK << 16;
|
||||
GPIOB->BSRR = (uint32_t)value & DATA_MASK;
|
||||
short_delay();
|
||||
GPIOA->BSRR = (uint32_t)WE_PIN << 16;
|
||||
short_delay();
|
||||
GPIOA->BSRR = WE_PIN;
|
||||
short_delay();
|
||||
}
|
||||
|
||||
static void g474_write_command(pnand_octet_t value)
|
||||
{
|
||||
GPIOA->BSRR = CLE_PIN | ((uint32_t)ALE_PIN << 16);
|
||||
write_cycle(value);
|
||||
GPIOA->BSRR = (uint32_t)CLE_PIN << 16;
|
||||
}
|
||||
|
||||
static void g474_write_address(pnand_octet_t value)
|
||||
{
|
||||
GPIOA->BSRR = ALE_PIN | ((uint32_t)CLE_PIN << 16);
|
||||
write_cycle(value);
|
||||
GPIOA->BSRR = (uint32_t)ALE_PIN << 16;
|
||||
}
|
||||
|
||||
static void g474_write_data(pnand_octet_t value)
|
||||
{
|
||||
GPIOA->BSRR = ((uint32_t)(CLE_PIN | ALE_PIN) << 16);
|
||||
write_cycle(value);
|
||||
}
|
||||
|
||||
static pnand_octet_t g474_read_data(void)
|
||||
{
|
||||
pnand_octet_t value;
|
||||
data_input();
|
||||
GPIOA->BSRR = ((uint32_t)(CLE_PIN | ALE_PIN | RE_PIN) << 16);
|
||||
short_delay();
|
||||
value = (pnand_octet_t)(GPIOB->IDR & DATA_MASK);
|
||||
GPIOA->BSRR = RE_PIN;
|
||||
short_delay();
|
||||
return value;
|
||||
}
|
||||
|
||||
static int g474_is_ready(void) { return (GPIOA->IDR & RB_PIN) != 0U; }
|
||||
static void g474_set_wp(int enabled)
|
||||
{
|
||||
GPIOA->BSRR = enabled ? ((uint32_t)WP_PIN << 16) : WP_PIN;
|
||||
}
|
||||
static void g474_delay_us(unsigned long us)
|
||||
{
|
||||
uint32_t cycles = (SystemCoreClock / 3000000UL) * (uint32_t)us;
|
||||
while (cycles-- != 0U) __NOP();
|
||||
}
|
||||
|
||||
static const parallel_nand_port_t g474_port = {
|
||||
g474_init, g474_select, g474_deselect,
|
||||
g474_write_command, g474_write_address, g474_write_data,
|
||||
g474_read_data, g474_is_ready, g474_set_wp, g474_delay_us
|
||||
};
|
||||
|
||||
const parallel_nand_port_t *parallel_nand_port_stm32g474ce(void)
|
||||
{
|
||||
return &g474_port;
|
||||
}
|
||||
Reference in New Issue
Block a user