I have been trying to code up some SIO port functions to deal with the PSP remote control. I have run into some problems in trying to do so and I am starting to wonder if it can be done with only the init, write, and read commands that LUA provides. I am pretty sure that I have to sequencing correct, but the remote seems to be sending the some block of bytes over and over again. It almost seems like the serial read buffer gets stuck or something. If anyone else has tried this I would be interested in sharing code.
Todd
Communicating with PSP remote through serial port
Moderators: Shine, Insert_witty_name
Well, I thought that I may as well post the code to see if anyone wants to take a shot at it. It isn' t the best, but I think that it is pretty solid for what it is supposed to do. The only real thing missing is the fact that right now it is only setup to send a single message to the remote but that is enough for testing and it doesn't even get that far anyway.
Todd
Todd
Code: Select all
-- PSP remote control test code for SIO port
sio_buffin = ""
sio_buffout = ""
sio_bytein = nil
sio_byteout = nil
sio_index = 0
sio_phase = nil
-- remote presence variables
-- remote = 0 : remote is missing
-- remote = 1 : remote is missing, user informed
-- remote = 2 : remote is present
-- remote = 3 : remote is present, user informed
sio_remote = 0
sio_reset = 0
sio_rts = 0
sio_cts = 0
sio_countF0 = 0
sio_rxmsgs = 0
sio_txmsgs = 0
time = 0
sio_time = 0
sio_timep = 0
ping = 0
-- different print positions for header and actual data
terminalHeadX = 0
terminalHeadY = 0
terminalX = 0
terminalY = 3
green = Color.new(0, 255, 0)
blue = Color.new(0, 0, 255)
black = Color.new(0, 0, 0)
terminal = Image.createEmpty(480, 272)
function scroll(image, dx, dy)
new = Image.createEmpty(image:width(), image:height())
new:blit(dx, dy, image)
return new
end
function terminalMaxY()
if terminalY >= 31 then
terminalY = 30
terminal = scroll(terminal, 0, -24)
end
end
function UpdateScreen()
screen:blit(0, 0, terminal, 0, 0, terminal:width(), terminal:height(), false)
screen.waitVblankStart()
screen:flip()
end
function printTerminal(text, color)
if color == nil then
color = green
end
for index_j = 1, string.len(text) do
char = string.sub(text, index_j, index_j)
if char == "\n" then
terminalHeadY = terminalHeadY + 1
terminalHeadX = 0
else
terminal:print(terminalHeadX * 8, terminalHeadY * 8, char, color)
terminalHeadX = terminalHeadX + 1
if terminalHeadX >= 60 then
terminalHeadX = 0
terminalHeadY = terminalHeadY + 1
end
end
end
end
function normalizeLinefeed(text)
-- terminal programs like Hyperterminal sends just a \r for return key, convert it
result = ""
for index_k = 1, string.len(text) do
char = string.sub(text, index_k, index_k)
if char == "\r" then char = "\n" end
result = result .. char
end
return result
end
function printTerminalHex(text, color, index_stamp)
if color == nil then
color = green
end
for index_l = 1, string.len(text) do
char_num = string.byte(text, index_l)
char_hex = formatNumbertoHex(char_num)
terminal:print(terminalX * 8, terminalY * 8, char_hex, color)
if index_stamp ~= nil then
printTerminalIndex(index_stamp)
end
terminalX = terminalX + 2
if terminalX >= 60 then
terminalX = 0
terminalY = terminalY + 3
end
terminalMaxY()
end
end
function printTerminalIndex(index_num)
index_hex = formatNumbertoHex(index_num)
terminal:print((terminalX) * 8, (terminalY + 1) * 8, index_hex, green)
end
function formatNumbertoHex(number)
result = ""
if number <= 9 then
result = string.format("0%d", number)
else
result = string.format("%2X", number)
end
return result
end
function printTerminalAlpha(text, color)
if color == nil then
color = green
end
for index_m = 1, string.len(text) do
char = string.sub(text, index_m, index_m)
if char == "\n" then
terminalY = terminalY + 1
terminalX = 0
else
terminal:print(terminalX * 8, terminalY * 8, char, green)
terminalX = terminalX + 1
if terminalX >= 60 then
terminalX = 0
terminalY = terminalY + 3
end
end
terminalMaxY()
end
end
-- begin main program loop
printTerminal("serial init... ", green)
System.sioInit(4800)
System.sleep(30)
sio_buffin = System.sioRead()
if sio_buffin ~= "" then
sio_remote = 2
end
while time < 6000 do
if sio_buffin == "" then
sio_buffin = System.sioRead()
end
if sio_remote <= 1 then
if sio_remote == 0 then
printTerminal("remote missing... ", green)
sio_remote = 1
end
if sio_buffin ~= "" then
if string.byte(sio_buffin, 1) == 0x00 then
sio_buffin = string.sub(sio_buffin, 2, -1)
end
sio_remote = 2
end
end
if sio_remote == 2 then
printTerminal("remote present...\n", green)
printTerminal("starting echo... ", green)
sio_remote = 3
end
if sio_buffin ~= "" then
sio_timep = sio_time
sio_time = time
for index_n = 1, string.len(sio_buffin) do
sio_bytein = string.byte(sio_buffin, index_n)
-- check for frame start
if sio_bytein == 0xF0 then
-- remove extra frame start
if sio_countF0 >= 5 or sio_countF0 == -1 then
sio_byteout = 0xF8
sio_index = 1
sio_countF0 = -1
end
if sio_countF0 ~= -1 then
sio_countF0 = sio_countF0 + 1
end
end
-- check for frame okay to send
if sio_bytein == 0xF8 then
sio_cts = 1
sio_txmsgs = sio_txmsgs + 1
end
-- check if remote was removed
if sio_bytein == 0x00 then
if (sio_time - sio_timep) > 60 then
sio_reset = 1
end
end
-- check command and set frame acknowledge
if sio_index == 3 and sio_bytein ~= 0xFE then
if (sio_bytein & 0x01) == 0 then
sio_phase = 0xFA
else
sio_phase = 0xFB
end
end
-- check for frame end
if sio_bytein == 0xFE then
sio_byteout = sio_phase
sio_index = 0
sio_msgs = sio_rxmsgs + 1
else
sio_index = sio_index + 1
end
end
printTerminalHex(sio_buffin, nil, nil)
sio_buffin = ""
end
if sio_byteout ~= nil then
System.sioWrite(string.char(sio_byteout))
printTerminalHex(string.char(sio_byteout), blue, nil)
sio_byteout = nil
end
if sio_rxmsgs >= 2 and sio_remote == 3 then
if sio_rts == 0 then
printTerminal("remote init... ", green)
System.sioWrite(string.char(0xF0))
printTerminalHex(string.char(0xF0), blue, nil)
sio_rts = 1
end
end
if sio_cts == 1 then
if sio_txmsgs == 1 then
sio_buffout = string.char(0xFD, 0x03, 0x01, 0x02, 0xFE)
elseif sio_txmsgs == 2 then
sio_buffout = string.char(0xFD, 0x02, 0x00, 0x02, 0xFE)
end
sio_cts = 0
end
if sio_buffout ~= "" then
System.sioWrite(sio_buffout)
printTerminalHex(sio_buffout, blue, nil)
sio_buffout = ""
end
if sio_reset == 1 then
terminal:fillRect(0, 0, 480, 16)
terminalHeadX = 0
terminalHeadY = 0
UpdateScreen()
sio_reset = 0
sio_remote = 0
end
ping = ping + 1
if ping == 60 then
ping = 0
printTerminalAlpha(" :", nil)
end
keypad = Controls.read()
if keypad:start() then
break
elseif keypad:select() then
while Controls.read():select() == false do
end
end
UpdateScreen()
time = time + 1
end