27.08.2019, 20:49
ну в общем как то так
проверил на контроллерах PS1 и PS2, работает, правда джой PS2 как то через раз читается, но это скорей всего проблема в неправильной скорости
Код:
#define SCIREG(x) *((volatile uint8 *)(x))
#define SCSMR1 SCIREG(0xFFE00000)
#define SCBRR1 SCIREG(0xFFE00004)
#define SCSCR1 SCIREG(0xFFE00008)
#define SCTDR1 SCIREG(0xFFE0000C)
#define SCSSR1 SCIREG(0xFFE00010)
#define SCRDR1 SCIREG(0xFFE00014)
#define SCSPTR1 SCIREG(0xFFE00018)
#define TDRE 0x80
#define RDRF 0x40
#define ORER 0x20
#define STBCR SCIREG(0xFFC00004)
#define PCTRA *((volatile uint32 *)(0xFF80002C))
#define PDTRA *((volatile uint16 *)(0xFF800030))
#define CSIO (1 << 14)
#define CS(x) PDTRA = (x == 0) ? (PDTRA | 0x80) : (PDTRA & ~0x80)
void sci_init(int baud_rate)
{
uint8 scsmr1 = 0x80, scbrr1;
STBCR &= ~1;
SCSCR1 = 0;
if (baud_rate > 100000)
{
scbrr1 = (50000000 / (4 * baud_rate)) - 1;
}
else if (baud_rate > 15000)
{
scbrr1 = (50000000 / (16 * baud_rate)) - 1;
scsmr1 = 0x81;
}
else if (baud_rate > 4000)
{
scbrr1 = (50000000 / (64 * baud_rate)) - 1;
scsmr1 = 0x82;
}
else if (baud_rate > 750)
{
scbrr1 = (50000000 / (256 * baud_rate)) - 1;
scsmr1 = 0x83;
}
else
{
printf("ERROR: speed %d not supported\n", baud_rate);
return;
}
SCSMR1 = scscr1;
SCBRR1 = scbrr1;
for(int i = 0; i < 800000; i++)
__asm__("nop");
SCSCR1 = 0x30;
PCTRA |= CSIO;
}
int sci_spi_rw(uint8 *in, uint8 *out, uint32 len)
{
for (uint32 i = 0; i < len; i++)
{
CS(1);
while (!(SCSSR1 & TDRE));
SCTDR1 = in[i];
SCSSR1 &= ~TDRE;
do
{
if (SCSSR1 & ORER)
{
return -1;
}
}
while (!(SCSSR1 & RDRF));
out[i] = SCRDR1;
SCSSR1 &= ~RDRF;
CS(0);
}
return 0;
}
проверил на контроллерах PS1 и PS2, работает, правда джой PS2 как то через раз читается, но это скорей всего проблема в неправильной скорости