Commit 442aaea3 authored by Alessio Igor Bogani's avatar Alessio Igor Bogani
Browse files

Finish to introduce rpmsg

parent 15e04952
......@@ -48,6 +48,44 @@ FILENAME : ControlLoop.c DESIGN REF: MC18
*/
#include <stdint.h>
//#include <stdio.h>
#include <pru_cfg.h>
#include <pru_intc.h>
//#include <rsc_types.h>
#include <pru_rpmsg.h>
#include "resource_table_0.h"
#include <limits.h>
#include <float.h>
volatile register uint32_t __R31;
/* Host-0 Interrupt sets bit 30 in register R31 */
#define HOST_INT ((uint32_t) 1 << 30)
/* The PRU-ICSS system events used for RPMsg are defined in the Linux device tree
* PRU0 uses system event 16 (To ARM) and 17 (From ARM)
* PRU1 uses system event 18 (To ARM) and 19 (From ARM)
*/
#define TO_ARM_HOST 16
#define FROM_ARM_HOST 17
/*
* Using the name 'rpmsg-pru' will probe the rpmsg_pru driver found
* at linux-x.y.z/drivers/rpmsg/rpmsg_pru.c
*/
#define CHAN_NAME "rpmsg-pru"
#define CHAN_DESC "Channel 30"
#define CHAN_PORT 30
/*
* Used to make sure the Linux drivers are ready for RPMsg communication
* Found at linux-x.y.z/include/uapi/linux/virtio_config.h
*/
#define VIRTIO_CONFIG_S_DRIVER_OK 4
uint8_t payload[RPMSG_MESSAGE_SIZE];
#define HWREG(x) (*((volatile unsigned int *)(x)))
#define HWREGH(x) (*((volatile unsigned short *)(x)))
......@@ -79,9 +117,14 @@ FILENAME : ControlLoop.c DESIGN REF: MC18
volatile int Run; // while 0xFFFF run compensator
volatile float OutputCurrent;
struct {
struct pru2pru_data_transfer {
float OCnorm;
} PRUDirectTransfer;
} p2pdt;
struct pru2user_data_transfer {
float SetPoint;
unsigned long int IOStatus;
} p2udt;
volatile float SetPoint;
volatile unsigned long int IOStatus;
volatile float Debug0,Debug1,Debug2,Debug3;
......@@ -103,8 +146,19 @@ float sum(float, float);
int main(void)
{
struct pru_rpmsg_transport transport;
uint16_t src, dst, len;
volatile uint8_t *status;
/* Allow OCP master port access by the PRU so the PRU can read external memories */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
//enable OCP master ports in SYSCFG (PRU_ICSS_CFG)
HWREG(0x26004) = 0x2A;
//HWREG(0x26004) = 0x2A;
/* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
PRU0FirmRev = 20210422;
trigger = 1; //for pulse operation
timer = 0;
......@@ -120,6 +174,24 @@ int main(void)
SetPWM();
__delay_cycles(200000);
/* Make sure the Linux drivers are ready for RPMsg communication */
status = &pru_remoteproc_ResourceTable.rpmsg_vdev.status;
while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));
/* Initialize the RPMsg transport structure */
pru_rpmsg_init(&transport, &pru_remoteproc_ResourceTable.rpmsg_vring0, &pru_remoteproc_ResourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
/* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);
while (1) {
/* Check bit 30 of register R31 to see if the ARM has kicked us */
if (__R31 & HOST_INT) {
/* Clear the event status */
CT_INTC.SICR_bit.STS_CLR_IDX = FROM_ARM_HOST;
break;
}
}
while(1)
{
if((Run == 0xffff) && ((IOStatus & 0xfffffffe) == 0)) // checks if a ON command issued and any error but only GATE OFF (LSB)
......@@ -156,8 +228,8 @@ int main(void)
HWREG(0x481AC194) = 0b10; // GPIO2_SETDATAOUT gpio2_1
#endif
__xin(10, 5, 0, PRUDirectTransfer);
OutputCurrent = PRUDirectTransfer.OCnorm; // read from PRU adc normalized value
__xin(10, 5, 0, p2pdt);
OutputCurrent = p2pdt.OCnorm; // read from PRU adc normalized value
Compensator(SetPoint, OutputCurrent);
ReadIO();
......@@ -200,6 +272,13 @@ int main(void)
}
ReadIO();
}
if (SetPoint != p2udt.SetPoint || IOStatus != p2udt.IOStatus) {
if (pru_rpmsg_receive(&transport, &src, &dst, &p2udt, &len) == PRU_RPMSG_SUCCESS) {
p2udt.SetPoint = SetPoint;
p2udt.IOStatus = IOStatus;
pru_rpmsg_send(&transport, dst, src, &p2udt, len);
}
}
}
}
......
......@@ -35,14 +35,17 @@ FILENAME : ReadADC.c DESIGN REF: MC18
Debug2 = OCnorm
*/
#include <stdint.h> // Is it necessary?
#include <stdio.h> // Is it necessary?
#include <pru_cfg.h> // Is it necessary?
#include <pru_intc.h> // Is it necessary?
#include <rsc_types.h> // Is it necessary?
#include <pru_rpmsg.h> // Is it necessary?
#include <stdint.h>
//#include <stdio.h>
#include <pru_cfg.h>
#include <pru_intc.h>
//#include <rsc_types.h>
#include <pru_rpmsg.h>
#include "resource_table_1.h"
#include <limits.h>
#include <float.h>
volatile register uint32_t __R31;
/* Host-1 Interrupt sets bit 31 in register R31 */
......@@ -112,10 +115,15 @@ volatile unsigned int ADC0, ADC1, ADC2, ADC3, ADC4, ADC5, ADC6;
// ADC0=Aux V, ADC1=Heater temp, ADC2=Out V, ADC3=dc link, ADC4=3.3V, ADC5=heatsink temp, ADC6=5V
volatile unsigned int PRU1FirmRev;
volatile float Debug0,Debug1,Debug2,Debug3;
struct {
struct pru2pru_data_transfer {
float OCnorm;
} p2pdt;
volatile float OCnorm, OCnorm_previous;
struct pru2user_data_transfer {
float OCnorm;
} PRUDirectTransfer;
volatile float OCnorm;
unsigned int OVnorm;
} p2udt;
void SetSPI();
void SetADCBB();
......@@ -159,6 +167,9 @@ int main(void)
ADC0=0;ADC1=0;ADC2=0;ADC3=0;ADC4=0;ADC5=0;ADC6=0;
PRU1FirmRev = 20210415;
Debug0, Debug1, Debug2, Debug3 = 0;
p2udt.OCnorm = FLT_MAX;
p2udt.OVnorm = UINT_MAX;
//init SPI
SetSPI();
......@@ -234,10 +245,10 @@ int main(void)
// 20us execution time
// OutputCurrent = -mpy(sumf(mpy(sumf(mpy(sumf(mpy(sumf(mpy(sumf(mpy(ScaleA5,OCnorm),ScaleA4),OCnorm),ScaleA3),OCnorm),ScaleA2),OCnorm),ScaleA1),OCnorm),ScaleA0),20.0);
// 7us execution time
//PRUDirectTransfer.Current= mpy(-20, OCnorm);
PRUDirectTransfer.OCnorm = OCnorm;
//pru_direct_transfer.Current= mpy(-20, OCnorm);
p2pdt.OCnorm = OCnorm;
__xout(10, 5, 0, PRUDirectTransfer);
__xout(10, 5, 0, p2pdt);
#ifdef benchmark1
HWREG(0x481ac190) = 0b1000000000;// gpio2_9 P8_44 // GPIO2_CLEARDATAOUT
......@@ -256,12 +267,13 @@ int main(void)
//ADC6 &= 0xff0; // read only one channel for digital FF
//ff=mpy((ADC6+0.0),0.005);
#if 0
if (pru_rpmsg_receive(&transport, &src, &dst, &Output, &len) == PRU_RPMSG_SUCCESS) {
//Output.Voltage = ADC2;
pru_rpmsg_send(&transport, dst, src, &Output, len);
if (OCnorm != p2udt.OCnorm || ADC2 != p2udt.OVnorm) {
if (pru_rpmsg_receive(&transport, &src, &dst, &p2udt, &len) == PRU_RPMSG_SUCCESS) {
p2udt.OCnorm = OCnorm;
p2udt.OVnorm = ADC2;
pru_rpmsg_send(&transport, dst, src, &p2udt, len);
}
}
#endif
}
}
......
/*
* Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* ======== resource_table_empty.h ========
*
* Define the resource table entries for all PRU cores. This will be
* incorporated into corresponding base images, and used by the remoteproc
* on the host-side to allocated/reserve resources. Note the remoteproc
* driver requires that all PRU firmware be built with a resource table.
*
* This file contains an empty resource table. It can be used either as:
* 1) A template, or
* 2) As-is if a PRU application does not need to configure PRU_INTC
* or interact with the rpmsg driver
*/
#ifndef _RSC_TABLE_PRU_H_
#define _RSC_TABLE_PRU_H_
#include <stddef.h>
#include <rsc_types.h>
#include "pru_virtio_ids.h"
/*
* Sizes of the virtqueues (expressed in number of buffers supported,
* and must be power of 2)
*/
#define PRU_RPMSG_VQ0_SIZE 16
#define PRU_RPMSG_VQ1_SIZE 16
/*
* The feature bitmap for virtio rpmsg
*/
#define VIRTIO_RPMSG_F_NS 0 //name service notifications
/* This firmware supports name service notifications as one of its features */
#define RPMSG_PRU_C0_FEATURES (1 << VIRTIO_RPMSG_F_NS)
/* Definition for unused interrupts */
#define HOST_UNUSED 255
/* Mapping sysevts to a channel. Each pair contains a sysevt, channel. */
struct ch_map pru_intc_map[] = { {16, 2},
{17, 0},
};
struct my_resource_table {
struct resource_table base;
uint32_t offset[2]; /* Should match 'num' in actual definition */
/* rpmsg vdev entry */
struct fw_rsc_vdev rpmsg_vdev;
struct fw_rsc_vdev_vring rpmsg_vring0;
struct fw_rsc_vdev_vring rpmsg_vring1;
/* intc definition */
struct fw_rsc_custom pru_ints;
};
#pragma DATA_SECTION(pru_remoteproc_ResourceTable, ".resource_table")
#pragma RETAIN(pru_remoteproc_ResourceTable)
struct my_resource_table pru_remoteproc_ResourceTable = {
1, /* we're the first version that implements this */
2, /* number of entries in the table */
0, 0, /* reserved, must be zero */
/* offsets to entries */
{
offsetof(struct my_resource_table, rpmsg_vdev),
offsetof(struct my_resource_table, pru_ints),
},
/* rpmsg vdev entry */
{
(uint32_t)TYPE_VDEV, //type
(uint32_t)VIRTIO_ID_RPMSG, //id
(uint32_t)0, //notifyid
(uint32_t)RPMSG_PRU_C0_FEATURES, //dfeatures
(uint32_t)0, //gfeatures
(uint32_t)0, //config_len
(uint8_t)0, //status
(uint8_t)2, //num_of_vrings, only two is supported
{ (uint8_t)0, (uint8_t)0 }, //reserved
/* no config data */
},
/* the two vrings */
{
FW_RSC_ADDR_ANY, //da, will be populated by host, can't pass it in
16, //align (bytes),
PRU_RPMSG_VQ0_SIZE, //num of descriptors
0, //notifyid, will be populated, can't pass right now
0 //reserved
},
{
FW_RSC_ADDR_ANY, //da, will be populated by host, can't pass it in
16, //align (bytes),
PRU_RPMSG_VQ1_SIZE, //num of descriptors
0, //notifyid, will be populated, can't pass right now
0 //reserved
},
{
TYPE_POSTLOAD_VENDOR, PRU_INTS_VER0 | TYPE_PRU_INTS,
sizeof(struct fw_rsc_custom_ints),
{
0x0000,
/* Channel-to-host mapping, 255 for unused */
0, HOST_UNUSED, 2, HOST_UNUSED, HOST_UNUSED,
HOST_UNUSED, HOST_UNUSED, HOST_UNUSED, HOST_UNUSED, HOST_UNUSED,
/* Number of evts being mapped to channels */
(sizeof(pru_intc_map) / sizeof(struct ch_map)),
/* Pointer to the structure containing mapped events */
pru_intc_map,
},
},
};
#endif /* _RSC_TABLE_PRU_H_ */
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment