SATA driver; AHCI port initialisation; Start (ST) command list; - driver

I have an issue with initialising and running AHCI port on my devboard.
Processor has SATA host controller with 2 ports implemented (port 0 & port 1). SSD drive w/ SATA interface is connected to the port 1.
According to "Serial ATA AHCI 1.3.1 Specification", chapter "10.3.1 Start (PxCMD.ST)" a bunch of conditions should be satisfied before setting PxCMD.ST to '1'. After setting this bit, PxCMD.CR should be set to indicate that port is ready and runs.
The problem is PxCMD.CR never comes to be set.
State before enabling PxCMD.ST:
port is in idle state, PxCMD.ST and PxCMD.CR are both '0'
FIS Receive Enable, PxCMD.FRE is '1'
Drive is connected to the port, PxSSTS = 0x00000133 (SSTS.IPM =
1, SSTS.SPD = 3, SSTS.DET = 3), PxTFD = 0x00000150 (TFD.STS.BSY
= 0, TFD.STS.DRQ = 0, TFD.STS.ERR = 0)
PxCLB/PxCLBU are set with physical addresses to buffer and buffer is aligned. (1KB buffer, 1KB aligned)
PxCMD = 0x00404010 (PxCMD.FBSCP = 1 & PxCMD.FRE = 1)
After setting PxCMD.ST, PxCMD = 0x00404011 and PxCMD.CR stays '0'
PxSERR = 0 stay the same. ERR is cleaned in advance before setting PxCMD.FRE
PxSCTL = 0x00000330 (IPM = 3, SPD = 3, DET = 0)
PxTFD = 0x00000150 stay the same
PxSIG = 0x00000101. The reg has 0xFFFFFFFF when drive is not connected.
Assuming that PxSIG is set and PxSERR is '0' more likely that PLL for SATA HC is set correctly.
I have concerns about PxTFD.ERR = 1 (when drive is disconnected PxTFD has default 0x7F value and PxTFD.ERR = 0) but didn't find is it relevant or nor considering that still TFD.STS.ERR = 0
Any ideal what is missed?
PS: It has nothing to do w/ Linux.

Related

writing to flash memory dspic33e

I have some questions regarding the flash memory with a dspic33ep512mu810.
I'm aware of how it should be done:
set all the register for address, latches, etc. Then do the sequence to start the write procedure or call the builtins function.
But I find that there is some small difference between what I'm experiencing and what is in the DOC.
when writing the flash in WORD mode. In the DOC it is pretty straightforward. Following is the example code in the DOC
int varWord1L = 0xXXXX;
int varWord1H = 0x00XX;
int varWord2L = 0xXXXX;
int varWord2H = 0x00XX;
int TargetWriteAddressL; // bits<15:0>
int TargetWriteAddressH; // bits<22:16>
NVMCON = 0x4001; // Set WREN and word program mode
TBLPAG = 0xFA; // write latch upper address
NVMADR = TargetWriteAddressL; // set target write address
NVMADRU = TargetWriteAddressH;
__builtin_tblwtl(0,varWord1L); // load write latches
__builtin_tblwth(0,varWord1H);
__builtin_tblwtl(0x2,varWord2L);
__builtin_tblwth(0x2,varWord2H);
__builtin_disi(5); // Disable interrupts for NVM unlock sequence
__builtin_write_NVM(); // initiate write
while(NVMCONbits.WR == 1);
But that code doesn't work depending on the address where I want to write. I found a fix to write one WORD but I can't write 2 WORD where I want. I store everything in the aux memory so the upper address(NVMADRU) is always 0x7F for me. The NVMADR is the address I can change. What I'm seeing is that if the address where I want to write modulo 4 is not 0 then I have to put my value in the 2 last latches, otherwise I have to put the value in the first latches.
If address modulo 4 is not zero, it doesn't work like the doc code(above). The value that will be at the address will be what is in the second set of latches.
I fixed it for writing only one word at a time like this:
if(Address % 4)
{
__builtin_tblwtl(0, 0xFFFF);
__builtin_tblwth(0, 0x00FF);
__builtin_tblwtl(2, ValueL);
__builtin_tblwth(2, ValueH);
}
else
{
__builtin_tblwtl(0, ValueL);
__builtin_tblwth(0, ValueH);
__builtin_tblwtl(2, 0xFFFF);
__builtin_tblwth(2, 0x00FF);
}
I want to know why I'm seeing this behavior?
2)I also want to write a full row.
That also doesn't seem to work for me and I don't know why because I'm doing what is in the DOC.
I tried a simple write row code and at the end I just read back the first 3 or 4 element that I wrote to see if it works:
NVMCON = 0x4002; //set for row programming
TBLPAG = 0x00FA; //set address for the write latches
NVMADRU = 0x007F; //upper address of the aux memory
NVMADR = 0xE7FA;
int latchoffset;
latchoffset = 0;
__builtin_tblwtl(latchoffset, 0);
__builtin_tblwth(latchoffset, 0); //current = 0, available = 1
latchoffset+=2;
__builtin_tblwtl(latchoffset, 1);
__builtin_tblwth(latchoffset, 1); //current = 0, available = 1
latchoffset+=2;
.
. all the way to 127(I know I could have done it in a loop)
.
__builtin_tblwtl(latchoffset, 127);
__builtin_tblwth(latchoffset, 127);
INTCON2bits.GIE = 0; //stop interrupt
__builtin_write_NVM();
while(NVMCONbits.WR == 1);
INTCON2bits.GIE = 1; //start interrupt
int testaddress;
testaddress = 0xE7FA;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
testaddress += 2;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
testaddress += 2;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
testaddress += 2;
status = NVMemReadIntH(testaddress);
status = NVMemReadIntL(testaddress);
What I see is that the value that is stored in the address 0xE7FA is 125, in 0xE7FC is 126 and in 0xE7FE is 127. And the rest are all 0xFFFF.
Why is it taking only the last 3 latches and write them in the first 3 address?
Thanks in advance for your help people.
The dsPIC33 program memory space is treated as 24 bits wide, it is
more appropriate to think of each address of the program memory as a
lower and upper word, with the upper byte of the upper word being
unimplemented
(dsPIC33EPXXX datasheet)
There is a phantom byte every two program words.
Your code
if(Address % 4)
{
__builtin_tblwtl(0, 0xFFFF);
__builtin_tblwth(0, 0x00FF);
__builtin_tblwtl(2, ValueL);
__builtin_tblwth(2, ValueH);
}
else
{
__builtin_tblwtl(0, ValueL);
__builtin_tblwth(0, ValueH);
__builtin_tblwtl(2, 0xFFFF);
__builtin_tblwth(2, 0x00FF);
}
...will be fine for writing a bootloader if generating values from a valid Intel HEX file, but doesn't make it simple for storing data structures because the phantom byte is not taken into account.
If you create a uint32_t variable and look at the compiled HEX file, you'll notice that it in fact uses up the least significant words of two 24-bit program words. I.e. the 32-bit value is placed into a 64-bit range but only 48-bits out of the 64-bits are programmable, the others are phantom bytes (or zeros). Leaving three bytes per address modulo of 4 that are actually programmable.
What I tend to do if writing data is to keep everything 32-bit aligned and do the same as the compiler does.
Writing:
UINT32 value = ....;
:
__builtin_tblwtl(0, value.word.word_L); // least significant word of 32-bit value placed here
__builtin_tblwth(0, 0x00); // phantom byte + unused byte
__builtin_tblwtl(2, value.word.word_H); // most significant word of 32-bit value placed here
__builtin_tblwth(2, 0x00); // phantom byte + unused byte
Reading:
UINT32 *value
:
value->word.word_L = __builtin_tblrdl(offset);
value->word.word_H = __builtin_tblrdl(offset+2);
UINT32 structure:
typedef union _UINT32 {
uint32_t val32;
struct {
uint16_t word_L;
uint16_t word_H;
} word;
uint8_t bytes[4];
} UINT32;

Lua: publish different sensors data simultaneously to topic

I am able to publish a data of different sensors (like temperature value and motion detection as zero or one) one at a time on a specific topic ( topic/temp/motion) using Lua code and subscribe in on my android app however i am not able to publish it simultaneously on same topic or sub-topic. Some ideas or examples would be great.
Below are some major bits of Lua code used.
orgID = "quickstart" -- IoT Foundation organization ID
broker = "test.mosquitto.org" --orgID..".messaging.internetofthings.ibmcloud.com" -- IP or hostname of IoTF service
mqttPort = 1883 -- MQTT port (default 1883: non-secure)
userID = "" -- blank for quickstart
userPWD = "" -- blank for quickstart
macID = "18fe34e1b007" -- unique Device ID or Ethernet Mac Address <==== Modify this!
clientID = ":esp8266:18fe34e1b007" -- Client ID
count = 0 -- Test number of mqtt_do cycles
mqttState = 0 -- State control
topic = "topic/temp/motion"
led = 4
--gpio.mode(led,gpio.OUTPUT)
--dht sensor settings------------------------------
pin = 1
-- PIR initialization section
pir = 2
x= 0 -- variable for sending motion detection information in "0 or 1"
function DHT_do()
status, temp, humi, temp_dec, humi_dec = dht.read(pin)
--gpio.write(led, gpio.LOW)
end
function mqtt_do()
count = count + 1 -- tmr.alarm counter
------------------------------------------- pir conditional code
if gpio.read(pir) ~= last_state then
last_state = gpio.read(pir)
if last_state == 1 then
print("ON")
x = 1
gpio.write(led,gpio.HIGH)
else
print("OFF")
x = 0
gpio.write(led,gpio.LOW)
m:publish(topic,x, 0, 0,
function(conn)
print(x)
print("temp_data:"..temp)

How can I maximize throughput in Docker and Akka HTTP?

I am building a specific jig for performance measurement. I have a load generator, boom (https://github.com/rakyll/boom). With this I can generate a pretty decent amount of load.
I also have a Docker image containing nginx as a load balancer, and two Akka-HTTP based REST servers. These do nothing except count hits (they always just return 200).
Running one of these servers stand-alone (outside the Docker) I have been able to get 1000 hits/second. Not sure if that's good or not. In this Docker configuration that figure drops to about 220 hits/second. I was kinda expecting, well... 2000 hits/second or thereabouts. Higher would even be better. I'd be happy if I can find a way to get 3-4K hits/sec with this arrangement.
I often get an error message like this:
[9549] Get http://192.168.99.100:9090/dispatcher?reply_to=foo: dial tcp 192.168.99.100:9090: socket: too many open files
Tried running my Docker with --ulimit nofile=2048, but that didn't help. My application.conf for Akka is merely:
akka {
loglevel = "ERROR"
stdout-loglevel = "ERROR"
http.host-connection-pool.max-open-requests = 512
}
The server code:
object Main extends App {
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
println(":: Starting Simulator on port "+args(0))
Http().bindAndHandle(route, java.net.InetAddress.getLoopbackAddress.getHostAddress, args(0).toInt)
var hits = 0
var isTiming = false
var numSec = 1
lazy val route =
get {
path("dispatcher") {
if(isTiming) hits += 1
complete(StatusCodes.OK)
} ~
path("startTiming" / IntNumber) { sec =>
isTiming = true
hits = 0
numSec = sec
val timeUnit = FiniteDuration(sec, SECONDS)
system.scheduler.scheduleOnce(timeUnit){ isTiming = false }
complete(StatusCodes.OK)
} ~
path("tps") {
val tps = hits/numSec * 2
complete(s"""${args(0)}: TPS-$tps\n""")
}
}
}
Theory of operation: Start traffic flowing then call the /startTiming/10 endpoint (for a 10-second capture on one of the 2 servers). After 10 seconds, call /tps a couple of times and the timing node will return approx. hits/second (x2).
Any idea how I can get more performance out of this?

Wireshark does not get Scapy Modbus response

I'm running the code example below against a remote PLC with Wireshark running. Why do I only get the query (I should get the response too)? It seems that the PLC sends the response, since the output of Scapy says Received 1 packets, got 1 answers, remaining 0 packets.
Any ideas of why is this happening?
I also performed the sniffing using the sniff() function from Scapy but the result is the same (only get the query).
#! /usr/bin/env python
import logging
logging.getLogger("scapy").setLevel(1)
from scapy import *
from modLib import *
# IP for all transmissions
ip = IP(dst="192.168.10.131")
# Sets up the session with a TCP three-way handshake
# Send the syn, receive the syn/ack
tcp = TCP( flags = 'S', window = 65535, sport = RandShort(), dport = 502, options = [('MSS', 1360 ), ('NOP', 1), ('NOP', 1), ('SAckOK', '')])
synAck = sr1 ( ip / tcp )
# Send the ack
tcp.flags = 'A'
tcp.sport = synAck[TCP].dport
tcp.seq = synAck[TCP].ack
tcp.ack = synAck[TCP].seq + 1
tcp.options = ''
send( ip / tcp )
# Creates and sends the Modbus Read Holding Registers command packet
# Send the ack/push i.e. the request, receive the data i.e. the response
tcp.flags = 'AP'
adu = ModbusADU()
pdu = ModbusPDU03()
adu = adu / pdu
tcp = tcp / adu
data = sr1(( ip / tcp ), timeout = 2)
data.show()
# Acknowledges the response
# Ack the data response
# TODO: note, the 17 below should be replaced with a read packet length method...
tcp.flags = 'A'
tcp.seq = data[TCP].ack
tcp.ack = data[TCP] + 17
tcp.payload = ''
finAck = sr1( ip / tcp )
First, you have a bug in your code (which is present in the original version http://www.digitalbond.com/scadapedia/security-controls/scapy-modbus-extensions/), you need to add .seq there: tcp.ack = data[TCP].seq + 17.
As said in the comment, you could write tcp.ack = data[TCP].seq + len(data[TCP].payload).
Anyway it's generally useless to do the TCP stack's work for the kind of things you try to do.
I would do something like that:
from scapy import *
from modLib import *
import socket
sock = socket.socket()
sock.connect(("192.168.10.131", 502))
s = StreamSocket(sock, basecls=ModbusADU)
ans, unans = s.sr(ModbusADU()/ModbusPDU03())
ans.show()
Does this work better?

Can't save to Flash Memory?

I am using the following library <flash.h> to Erase/Write/Read from memory but unfortunately the data I am trying to save doesn't seem to be written to flash memory. I am using PIC18F87j11 with MPLAB XC8 compiler. Also when I read the program memory from PIC after attempting to write to it, there is no data on address 0x1C0CA. What am I doing wrong?
char read[1];
/* set FOSC clock to 8MHZ */
OSCCON = 0b01110000;
/* turn off 4x PLL */
OSCTUNE = 0x00;
TRISDbits.TRISD6 = 0; // set as ouput
TRISDbits.TRISD7 = 0; // set as ouput
LATDbits.LATD6 = 0; // LED 1 OFF
LATDbits.LATD7 = 1; // LED 2 ON
EraseFlash(0x1C0CA, 0x1C0CA);
WriteBytesFlash(0x1C0CA, 1, 0x01);
ReadFlash(0x1C0CA, 1, read[0]);
if (read[0] == 0x01)
LATDbits.LATD6 = 1; // LED 1 ON
while (1) {
}
I don't know what WriteFlashBytes does but the page size for your device is 64 bytes and after writing you need to write an ulock sequence to EECON2 and EECON1 registers to start programming the flash memory

Resources