This page tries to document what we find out about the Sony/Ericsson 3.5G Modem that is present in (at least) the E-TEN M800 / X800.

The modem is an Ericsson Mobile Platform (EMP) 360. It seems to be similar to http://www.stericsson.com/platforms/hspa_m365.jsp

  • connected via SPI and UART0 to the S3C2442B

SPI interface

  • uses SPIMISO1/SPIMOSI1/SPICLK1/nSS1 of S3C2442B
  • SPI controller registers suggest slave mode
  • SPI driver in WM6.1 uses DMA accelerated transfers
  • DMA Rx buffer address (according to register 0x4b0000dc): 0x3093f004
    HaRET(97)# pdump 0x3093f004 0x200
    3093f004 | 454d432b 52524520 203a524f b66f0d31 | +CME ERROR: 1.o.
    

protocol

The protocol is really weird, since AT commands are usually requests by the AP sent to the modem, so it would make lots of sense to make the AP the SPI master. As SPI master it could by itself initiate requests at any point in time.

In any case, for some reason the designers of the M800 did it the other way around: The modem is the SPI master, and the AP is the slave. So how does a typical transfer look like?

  • transfer of command from AP to modem
    • AP sets GPA16 (GSM_SPI_REQ) to one (tell the modem we want to Tx)
    • modem responds by asserting nSS1 and EINT16 (see below)
    • SPI transfer proceeds (CPOL=0, CPHA=0)
    • AP sets GPA16 (GSM_SPI_REQ) to zero (tell the modem we're done)
    • modem responds by de-asserting nSS1 and EINT16 (see below)

NOTE: nSS1 seems to be interconnected to EINT16, in order to assure the AP gets an interrupt whenever the modem wants to transmit something.

If we now actually take this microscopic nature of a single transfer into a bigger picture, we get something like:

  • nSS1 interrupt is raised by the modem
    • trigger DMA read of 4 bytes
      • DMA read:
        • configure SPI and DMA controllers
        • assert GPA16
        • wait for DMA completion interrupt (timeout 2sec, re-assert GPA16 if fails)
        • de-assert GPA16
    • check on first 16bit value in those 14 bytes (command)
      • command == 0x0001: do write of pending data to SPI
        • set state = 0
        • configure DMA, SPI
        • append 0xffff to the user buffer end
        • assert GPA16
        • wait for DMA completion
        • de-assert GPA16
        • set state = 3 and re-start from beginning (reading 4 bytes,...)
      • command == 0x0000: do read of pending data from SPI
        • set state = 1
        • configure DAM, SPI
        • assert GPA16
        • wait for DMA completion interrupt (timeout 2sec, re-assert GPA16 if fails)
        • de-assert GPA16
        • if first 16bit value == 0x0000, set state = 1
        • if first 16bit value == 0x0001, set state = 0
        • act according to new state. we never stop after a read ?!?
      • command == 0x0002: state = -1 and finish nSS1 interrupt handler
        • set state = -1

Serial Interface

in addition to the SPI interface, there is a UART connection. It is a full UART (including hardware RTS/CTS) and the X800/M800 use UART0 for this purpose.

protocol

the protocol is unclear at this point. knight/empire as well as usbdownloader use some binary protocols.

knight/empire

The Knight/Empire testing program exercises the following sequence to initialize the Modem:

  • CPLD 16-bit register 0x12 = 1 (enables red LED)
  • CPLD 16-bit register 0x14 = 2
  • GPB4 output mode = 0
  • GPA15 output mode = 0
  • GPA4 output mode = 0
  • GPF4 input mode
  • GPF4 pull-down enable
  • GPA11 output mode = 0
  • GPA15 output mode = 1
    • delay 3000 units
  • GPA 15 output mode = 0
  • GPB4 output mode = 0
    • delay 100 units
  • GPB4 output mode = 1
    • delay 20000 units
  • GPB4 output mode = 0
    • delay 50000 units

It then proceeds to actually transceiving data with the modem (at 115200 bps 8N1)

  • receive up to 200 bytes from the modem
  • a long delay
  • set GPA11 to output 1
  • a short delay (100 units)
  • send binary sequence (08) "0x02, 0x05, 0x00, 0x00, 0x03, 0x01, 0xd2, 0x02"
    • receive 8 bytes
  • send binary sequence (08) "0x02, 0x05, 0x00, 0x00, 0x01, 0x01, 0x62, 0x31"
  • send binary sequence (10) "0x02, 0x07, 0x00, 0x00, 0x00, 0x31, 0x09, 0x00, 0xe2, 0x3b"
    • receive 8 bytes
    • receive 7 bytes
    • receive 7 bytes
    • receive 11 bytes
  • send binary sequence (08) "0x02, 0x05, 0x00, 0x00, 0x01, 0x02, 0xf9, 0x03"
    • receive 8 bytes
  • send binary sequence (10) "0x02, 0x07, 0x00, 0x00, 0x00, 0x31, 0x09, 0x00, 0xe2, 0x3b"
    • receive 7 bytes
    • receive 7 bytes
    • receive 11 bytes
  • send binary sequence (10) "0x02, 0x05, 0x00, 0x00, 0x01, 0x03, 0x70, 0x12" (yes, we transmit 10 but only have 8?!?)
    • receive 8 bytes
  • send binary sequence (10) "0x02, 0x07, 0x00, 0x00, 0x00, 0x31, 0x09, 0x00 0xe2, 0x3b"
    • receive 7 bytes
    • receive 7 bytes
    • receive 11 bytes
  • send binary sequence (08) "0x02, 0x05, 0x00, 0x00, 0x01, 0x05, 0xcf, 0x66"
    • receive 7 bytes
    • receive 7 bytes
    • receive 11 bytes
  • send binary sequence (16) "0x02, 0x0d, 0x00, 0x81, 0x00 ..."
    • receive 80 bytes
USB downloader

The USB downloader on the Samsung Application Processor does the following:

  • CPLD[0x12] = 0x4 (switch on the RED LED)
  • some GPIO configuration
    • GPA4 mode output
    • GPB3 mode input, pull-down enable
    • GPF4 mode input, pull-down enable
    • GPF5 mode input, pull-down enable
    • GPH0..3 (UART0) mode function. pull-down for RTS/CTS
    • GPD1 mode output, level 0
    • GPH8 mode output, level 0
      • delay 0x1388 units
    • GPH8 mode output, level 1
      • delay 0x1338 units
    • GPH8 mode output, level 0
    • GPB4 mode output, level 1
  • actual data transfer
    • send 0x45 (E) and wait for the UART0 to return with 0x43 (C)
    • send 0x6a (j)
    • send the following sequence of packets five times:
      • 0x80, 0x04, 0x00, 0x98, 0x02, 0x08, 0x00
      • 0x80, 0x04, 0x00, 0x18, 0x02, 0x08, 0x00
      • 0x80, 0x04, 0x00, 0x90, 0x02, 0x08, 0x00
      • 0x80, 0x04, 0x00, 0x10, 0x02, 0x08, 0x00
      • 0x80, 0x04, 0x00, 0x90, 0x02, 0x02, 0x00
      • 0x80, 0x04, 0x00, 0x10, 0x02, 0x02, 0x00
      • 0x80, 0x04, 0x03, 0x00, 0x01, 0x01, 0x01
    • send the following packet:
      • 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00
    • send four bytes containing the size of the firmware
    • FIXME: not yet reviewed the remaining process

Linux CAIF Implenentation

Meanwhile, ST/Ericsson has submitted a Linux CAIF protocol implementation to the mainline kernel. The protocol traces we made seem to match what they write in their README file

Thus, if we can actually get the SPI talking/wokring/powered, we should have a finished official implementation of this multiplex protocol.