Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion doc_and_examples/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,31 @@
#Examples and documentations

##Pin mappings
DIO[0] to DIO[8] => pru0_r30_0 to pru0_r30_8
DIO[0] to DIO[7] => pru0_r30_0 to pru0_r30_7
pinmux.pdf contains the pru0_r30_x (pru format) GPIOy_z (GPIO format) mappings.
beaglebone_headers.png has the pin number in GPIO format to header pin mapping.

eg. searching for 'pru0_pru_r30_0' [ i.e. DIO[0] ] in pinmux.pdf gives us a corresponding 'gpio3_14'
looking up 'gpio3_14' in beaglebone_headers.png gives us header pin 'P9.31'.
Hence DIO[0] corresponds to 'P9.31'

Added support for access GPIOs other than __R30. Has to expanded for other GPIO modules (Currently GPIO0)

DIO[8] -> GPIO0_2 -> P9.22

DIO[9] -> GPIO0_3 -> P9.21

DIO[10] -> GPIO0_4 -> P9.18

DIO[11] -> GPIO0_5 -> P9.17

DIO[12] -> GPIO0_7 -> P9.42

DIO[13] -> GPIO0_8 -> P8.35

DIO[14] -> GPIO0_9 -> P8.33

DIO[15] -> GPIO0_10 -> P8.31

DIO[16] -> GPIO0_11 -> P8.32

6 changes: 5 additions & 1 deletion src/dts/BB-PRUSPEAK-00A0.dts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@
"P8.46", /* pru1: pr1_pru1_pru_r30_1 */
/* pru1: pr1_pru1_pru_r30_14 is on UART0_RXD */
/* pru1: pr1_pru1_pru_r30_15 is on UART0_TXD */
"P9.18", /*gpio0_4*/
"P9.17", /*gpio0_5*/
/* the hardware IP uses */
"pru0",
"pru1";
Expand Down Expand Up @@ -83,7 +85,9 @@
0x190 0x25 /* mcasp0_aclkx.pr1_pru0_pru_r30_0, MODE5 | OUTPUT | PRU */
0x03c 0x26 /* GPMC_AD15.pr1_pru0_pru_r31_15, MODE6 | INPUT | PRU*/
0x038 0x26 /* GPMC_AD14.pr1_pru0_pru_r31_14, MODE6 | INPUT | PRU*/

0x158 0x37 /* gpio0_4 -> P9.18 */
0x15c 0x37 /* gpio0_5 -> P9.17 */
0x164 0x37 /* gpio0_7 -> P9.42 */
//0x084 0x25 /* gpmc_csn2.pr1_pru1_pru_r30_13, MODE5 | OUTPUT | PRU */ --conflict with eMMC
//0x080 0x25 /* gpmc_csn1.pr1_pru1_pru_r30_12, MODE5 | OUTPUT | PRU */
0x0e0 0x25 /* lcd_vsync.pr1_pru1_pru_r30_8, MODE5 | OUTPUT | PRU */
Expand Down
64 changes: 48 additions & 16 deletions src/pru-firmware/pru0_firmware.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#include "pru0_firmware.h"

int var_loc[256];
void wait(int);
void wait(int,int);
int pwm_val = 0;

static void send_ret_value(int val)
Expand Down Expand Up @@ -73,12 +73,22 @@ int get_var_val(int addr)

return 0;
}

/*maps value to gpio modules*/
int map_gpio(int val)
{
if(val>7 && val<12){
return (val-6); // This is done because SET DIO[8], maps to GPIO0_2, thus 8 - 6 = 2
}
if(val>11 && val < 19){ // GPIO0_6 missing ? can't find on headers.
return (val-5); // SET DIO[12] onwards maps to GPIO0_7, 12 - 5 = 7.
}
}
/*instruction handlers*/

void dio_handler(int opcode, u32 inst)
{
int val1, val2;
int val1, val2,val3;
PRUCFG_SYSCFG = PRUCFG_SYSCFG & (~SYSCFG_STANDBY_INIT);
if(opcode == SET_DIO_a){
/* SET DIO[c/v], c/v */

Expand All @@ -102,15 +112,31 @@ void dio_handler(int opcode, u32 inst)
int addr = GET_BYTE(inst, 1) + index + 1;
val2 = var_loc[addr];
}
/* set hi*/
if(val2 && (val1 < MAX_DIO)){
__R30 = __R30 | ( 1 << val1);
}

/* set hi*/
if(val2 && (val1 < MAX_DIO)){

if(val1<8){
__R30 = __R30 | ( 1 << val1);
}
else{
val3 = map_gpio(val1);
mmio32(GPIO_OE) = mmio32(GPIO_OE) & ~(1 << val3);
mmio32(GPIO_SETDATAOUT) = (1<<(val3));
}
}
/* set low*/
else{
__R30 = __R30 & ~( 1 << val1);
}
else{
if(val1<8){
__R30 = __R30 & ~( 1 << val1);
}

else{
val3 = map_gpio(val1);
mmio32(GPIO_CLEARDATAOUT) = (1<<(val3));
}
}

PRUCFG_SYSCFG = PRUCFG_SYSCFG | SYSCFG_STANDBY_INIT;

if(single_command)
send_ret_value(val2 ? 1 : 0);
Expand Down Expand Up @@ -252,7 +278,7 @@ void array_dec_handler(int opcode, u32 inst)
void wait_goto_get_handler(int opcode, u32 inst)
{
int op = (GET_BYTE(inst, 2) >> 6);
int val;
int val,dec;
if(op == 0){
/* WAIT c*/
val = inst & 0xFFFF;
Expand All @@ -278,9 +304,14 @@ void wait_goto_get_handler(int opcode, u32 inst)
}

if(opcode == WAIT){
wait(val);
wait(val,0);
}

else if (opcode == WAIT_64){
inst = get_second_word();
dec = inst & 0xFFFF;
wait(val,dec);
}

else if (opcode == GOTO)
inst_pointer = val;

Expand Down Expand Up @@ -670,7 +701,7 @@ void check_event(void)

}

void wait(int ms)
void wait(int ms,int us)
{
/* set the CMP0 reg value */
//PIEP_CMP_CMP0 = MS * ms;
Expand All @@ -683,7 +714,7 @@ void wait(int ms)
PIEP_CMP_CFG |= CMP_CFG_CMP_EN(0);

/* set the CMP0 reg value */
PIEP_CMP_CMP0 = ((MS * ms) + PIEP_COUNT);// % 0xFFFFFFFF;//is the % op needed at all?
PIEP_CMP_CMP0 = ((MS * ms) + (uS * us) + PIEP_COUNT);// % 0xFFFFFFFF;//is the % op needed at all?

/* clear the timer event for CMP0 incase it has been already set by mistake */
PIEP_CMP_STATUS = CMD_STATUS_CMP_HIT(0);
Expand Down Expand Up @@ -730,6 +761,7 @@ void execute_instruction()
break;

case WAIT:
case WAIT_64:
case GOTO:
case GET:
wait_goto_get_handler(opcode, inst);
Expand Down
12 changes: 10 additions & 2 deletions src/pru-firmware/pru0_firmware.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
#define IF_EVENT PINTC_SRSR0 & (1 << EVENT_BIT)

#define MS 0x30d40 //number of clock cycles it takes for 1ms

#define uS 0xC8 //number of clock cycles it take for 1uS
/*max number of DIO pins*/
#define MAX_DIO 12
#define MAX_DIO 20

/* max data area (in terms of index for var_loc[])*/
#define MAX_DATA 239
Expand All @@ -19,6 +19,13 @@
Different syscall values, aliases and their meaning
*/

//GPIO0 module address
#define mmio32(x) (*(volatile unsigned long *)(x))
#define GPIO10 (0x44E07000)
#define GPIO_CLEARDATAOUT (GPIO10 + 0x190)
#define GPIO_SETDATAOUT (GPIO10 + 0x194)
#define GPIO_OE (GPIO10 + 0x134)

//DEBUG - Sets all output pins to high
#define SYS_DEBUG 0

Expand Down Expand Up @@ -98,6 +105,7 @@ extern void sc_downcall(int (*handler)(u32 nr, u32 arg0, u32 arg1, u32 arg2, u32
#define WAIT 20
#define GOTO 21
#define GET 22
#define WAIT_64 23

/*arithmetic instructions*/
#define ADD_32 48
Expand Down
6 changes: 4 additions & 2 deletions src/userspace_lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,11 +513,13 @@ WAIT x
```
where **x** (the only operand) can be of type **C or V or Arr[v]**

This is a 32 bit instruction.
This is a 32 bit instruction if milis argument is given and 64 bit
instruction if millis + micros argument is given.

**opcode**
```c
0x14 (20)
0x14 (20) for WAIT 100
0x17 (23) for WAIT 100.345
```
**operation**
```
Expand Down
14 changes: 10 additions & 4 deletions src/userspace_lib/pru_speak/bs_lex.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@
tokens = [
'VAR',
'INT',

'FLOAT',
'GTE', # '>='
'LTE', # '<='
'GT', # '>'
'LT', # '<'
'LT', # '<'
'EQ', # '=='
'NEQ', # '!='
] + reserved
Expand All @@ -62,7 +62,13 @@ def t_HEX_INT(t):

def t_INT(t):
'\d+'
t.value = int(t.value)
t.value = int(t.value)
return t
def t_FLOAT(t):
r'\.?[0-9]+'
t.value = float(t.value)
t.value = t.value*1000
t.value = int(t.value)
return t

def t_VAR(t):
Expand All @@ -77,7 +83,7 @@ def t_error(t):
print "Illegal character '%s'" % t.value[0]

lexer = lex.lex()
data = '''SET DIO[myvar], 1'''
data = '''WAIT 10.345'''
lexer.input(data)

if __name__ == '__main__':
Expand Down
35 changes: 24 additions & 11 deletions src/userspace_lib/pru_speak/bs_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ def byte_code_dec_array(name, val):
return pack_byte(OPCODE, byte2, byte1, byte0)


def byte_code_single_op(cmd, val):
def byte_code_single_op(cmd, val, flt):
'''
single operand instructions
e.g. WAIT, GOTO, GET
Expand All @@ -308,11 +308,10 @@ def byte_code_single_op(cmd, val):
}
OPCODE = opcode_dict[cmd]
byte2, byte1, byte0 = 0, 0, 0

byte7, byte6, byte5, byte4 = 0, 0, 0, 0
#incase wait or goto
if OPCODE < 22 and not script_mode:
return 0 #these inst only make sense in a script

if val.type == 'INT':
#case1 INT
byte2 = 0
Expand All @@ -323,9 +322,13 @@ def byte_code_single_op(cmd, val):
else:
byte0 = val.val & 0xFF #lower 8 bits
byte1 = (val.val >> 8) & 0xFF #higher 8 bits
if flt and OPCODE == 20: #check if decimal delay (uS) is present for WAIT command
OPCODE = OPCODE + 3 #make WAIT opcode 23. now a 64 bit instruction
byte3=OPCODE
byte4 = flt.val & 0xFF #lower 8 bits of uS
byte5 = (flt.val >> 8) & 0xFF #higher 8 bits uS
return pack_byte(OPCODE, byte2, byte1, byte0), pack_byte(byte7, byte6, byte5, byte4)



elif val.any_var:
#Var or Arr[Var]
byte2 = 0b01 << 6
Expand Down Expand Up @@ -668,20 +671,25 @@ def p_inst_LBL(p):
def add_label(byte_code, index):
return (byte_code & 0xFFFF0000) | (index & 0xFFFF)

def p_inst_WAIT(p):
def p_inst_WAIT_int(p):
'''inst : WAIT val'''
#print "WAIT command - val :", p[2]
p[0] = byte_code_single_op(p[1], p[2])
print "WAIT command - val :", p[2].val
p[0] = byte_code_single_op(p[1], p[2],0)

def p_inst_WAIT_float(p):
'''inst : WAIT val val''' #WAIT INT FLOAT
print "WAIT command - val :", p[3].val
p[0] = byte_code_single_op(p[1], p[2],p[3])

def p_inst_GOTO(p):
'''inst : GOTO val'''
#print "GOTO command - val :", p[2]
p[0] = byte_code_single_op(p[1], p[2])
p[0] = byte_code_single_op(p[1], p[2],0)

def p_inst_GET(p):
'''inst : GET val'''
#print "GET command - val :", p[2]
p[0] = byte_code_single_op(p[1], p[2])
p[0] = byte_code_single_op(p[1], p[2],0)

def p_inst_IF(p):
'''inst : IF '(' val cond val ')' GOTO val'''
Expand Down Expand Up @@ -747,6 +755,11 @@ def p_val_INT(p):
#print p[1]
p[0] = Value('INT', p[1])

def p_val_FLOAT(p):
'''val : FLOAT'''
#print p[1]
p[0] = Value('FLOAT', p[1])

def p_val_VAR(p):
'''val : VAR'''
p[0] = Value('VAR', p[1])
Expand Down Expand Up @@ -827,7 +840,7 @@ def p_error(p):
try :
print parser.parse("SET var1, 4")
#print pru_var_count
print parser.parse("GET DIO[0]")
print parser.parse("WAIT 100.34")
#print pru_var_count
print parser.parse("SET var1, DIO[0]")
except Exception as e:
Expand Down