lpcmanager

030c244f6e84
Parents ac9420feb6ab
Children cc123ca10682
Add Beremiz target definition template for SOM6 based PRODUCTs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SOM6Target/XSD.template Tue May 28 13:21:34 2019 +0200
@@ -0,0 +1,9 @@
+<xsd:element name="%(target_name)s">
+ <xsd:complexType>
+ <xsd:attribute name="Compiler" type="xsd:string" use="optional" default="$CC"/>
+ <xsd:attribute name="CFLAGS" type="xsd:string" use="optional" default="$CFLAGS"/>
+ <xsd:attribute name="Linker" type="xsd:string" use="optional" default="$CC"/>
+ <xsd:attribute name="LDFLAGS" type="xsd:string" use="optional" default="$LDFLAGS"/>
+ <xsd:attribute name="XenoConfig" type="xsd:string" use="optional"/>
+ </xsd:complexType>
+</xsd:element>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SOM6Target/plc_SOM6_main_retain.c Tue May 28 13:21:34 2019 +0200
@@ -0,0 +1,326 @@
+#include <alchemy/event.h>
+#include <alchemy/mutex.h>
+/*
+#include <rtdm/rtdm.h>
+#include <rtdm/spi_apf28_rtdm_ioctl.h>
+*/
+#include <xenomai/init.h>
+
+/* SPI configurable parameters */
+/* --------------------------- */
+/* SPI CLK MODE */
+#define TEST_SPI_CLK_PHASE RTDM_SPI_CLKPHASE_LOW
+#define TEST_SPI_CLK_POLARITY RTDM_SPI_CLKPOLARITY_LOW
+/* Frequency : 5MHz */
+#define TEST_SPI_SPEED 20000000
+/* 16 bits per word */
+#define TEST_SPI_BITS_PER_WORD RTDM_SPI_8BPW
+/* Chip selects */
+#define TEST_SPI_CHIPSELECT1 RTDM_SPI_SS0
+#define TEST_SPI_CHIPSELECT2 RTDM_SPI_SS0
+/* Use the DMA from transfer > 4 bytes */
+#define TEST_SPI_DMA_BYTES_MIN 4
+
+#define NVRAM_SIZE 0x8000
+#define IDLEN 4
+#define CMDSIZE 3
+#define RETAIN_BUFFER_SIZE (NVRAM_SIZE - IDLEN)
+
+static RT_TASK RETAIN_task;
+static RT_MUTEX RETAIN_Mutex;
+static RT_EVENT RETAIN_Event;
+
+#pragma pack(push,1)
+/* Data protected by mutex */
+static struct priv_s {
+ unsigned char cmd[CMDSIZE];
+ struct buf_s {
+ unsigned char id[IDLEN];
+ unsigned char vars[RETAIN_BUFFER_SIZE];
+ } buf;
+} priv;
+#pragma pack(pop)
+
+static unsigned short actual_size;
+static int retain_busy = 0;
+/* 0 : PLC can update. No SPI transmission undergoing
+ 1 : PLC cannot update. SPI transmission undergoing */
+
+static int fd_spi;
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+static uint8_t rcmd[] = {
+ /* Read, Addresssse */
+ 0x03, 0x00, 0x00,
+};
+
+int SPI_Read(void *buf, unsigned int len){
+/*
+ int status;
+ int size;
+ unsigned int uint;
+ uint = 1;
+ if (ioctl(fd_spi, RTDM_SPI_LOCK_CS_SET, &uint) < 0) {
+ printf("Failed to lock CS\n");
+ return 0;
+ }
+
+ status = write(fd_spi, rcmd, ARRAY_SIZE(rcmd));
+ if (status < 0) {
+ fprintf(stderr, "Failed to send read command. ERR : %d\n", status);
+ return 0;
+ }
+
+ uint = 0;
+ if (ioctl(fd_spi, RTDM_SPI_LOCK_CS_SET, &uint) < 0) {
+ printf("Failed to unlock CS\n");
+ return 0;
+ }
+
+ size = read(fd_spi, buf, len);
+ if (size != len) {
+ fprintf(stderr, "Failed to read %d bytes on the SPI bus. size : %d\n",
+ len, size);
+ return 0;
+ }
+
+ return size;
+ */
+ return -EIO;
+}
+
+int SPI_Write(void *buf, unsigned int len){
+ /*
+ int status;
+ status = write(fd_spi, buf, len);
+ if (status < 0) {
+ fprintf(stderr, "Failed to write memory. ERR : %d\n", status);
+ return 0;
+ }
+ return len;
+ */
+ return -EIO;
+}
+
+static void SPI_init(void)
+{
+#if 0
+ unsigned long ulong;
+ unsigned int uint;
+
+ /* Open the SPI RTDM device */
+ if ((fd_spi = open("/dev/rtdm/spi_apf28_rtdm", 0)) < 0) {
+ printf("rt_spi_open error\n");
+ return;
+ }
+
+ /* Bus configuration */
+
+ /* Clock phase */
+ uint = TEST_SPI_CLK_PHASE;
+ if (ioctl(fd_spi, RTDM_SPI_CLKPHASE_SET, &uint) < 0) {
+ printf("Failed to configure the clock phase\n");
+ return;
+ }
+ if (ioctl(fd_spi, RTDM_SPI_CLKPHASE_GET, &uint) < 0) {
+ printf("Failed to get the clock phase\n");
+ return;
+ }
+
+ /* Clock polarity */
+ uint = TEST_SPI_CLK_POLARITY;
+ if (ioctl(fd_spi, RTDM_SPI_CLKPOLARITY_SET, &uint) < 0) {
+ printf("Failed to configure the clock polarity\n");
+ return;
+ }
+ if (ioctl(fd_spi, RTDM_SPI_CLKPOLARITY_GET, &uint) < 0) {
+ printf("Failed to get the clock polarity\n");
+ return;
+ }
+
+ /* Frequency */
+ ulong = TEST_SPI_SPEED;
+ if (ioctl(fd_spi, RTDM_SPI_FREQ_SET, &ulong) < 0) {
+ printf("Failed to configure the frequency\n");
+ return;
+ }
+ if (ioctl(fd_spi, RTDM_SPI_FREQ_GET, &ulong) < 0) {
+ printf("Failed to get the frequency\n");
+ return;
+ }
+
+ /* Bits per word */
+ uint = TEST_SPI_BITS_PER_WORD;
+ if (ioctl(fd_spi, RTDM_SPI_BITSPERWORD_SET, &uint) < 0) {
+ printf("Failed to configure the BPW\n");
+ return;
+ }
+ if (ioctl(fd_spi, RTDM_SPI_BITSPERWORD_GET, &uint) < 0) {
+ printf("Failed to get the BPW\n");
+ return;
+ }
+
+ /* Chipselect */
+ uint = TEST_SPI_CHIPSELECT1;
+ if (ioctl(fd_spi, RTDM_SPI_CHIPSELECT_SET, &uint) < 0) {
+ printf("Failed to configure the chip select\n");
+ return;
+ }
+ if (ioctl(fd_spi, RTDM_SPI_CHIPSELECT_GET, &uint) < 0) {
+ printf("Failed to get the chip select\n");
+ return;
+ }
+
+ /* DMA usage definition */
+ uint = TEST_SPI_DMA_BYTES_MIN;
+ if (ioctl(fd_spi, RTDM_SPI_DMA_SET, &uint) < 0) {
+ printf("Failed to configure the DMA threshold\n");
+ return;
+ }
+ if (ioctl(fd_spi, RTDM_SPI_DMA_GET, &uint) < 0) {
+ printf("Failed to get the DMA threshold\n");
+ return;
+ }
+
+ /* Prepare for future write commands */
+ /* Write Command*/
+ priv.cmd[0] = 0x02;
+ /* Write Addresssse */
+ priv.cmd[1] = 0x00;
+ priv.cmd[2] = 0x00;
+#endif
+}
+
+int NVRAM_Done = 0;
+
+void NVRAM_Init(void){
+ int status;
+ /* Set Sequencial access mode */
+ uint8_t mbuf[] = {
+ /* Mode, Sequ */
+ 0x01, 0x40,
+ };
+
+ // status = write(fd_spi, mbuf, ARRAY_SIZE(mbuf));
+ status = -EIO;
+ if (status < 0) {
+ printf("Failed to change mode. ERR : %d\n", status);
+ return;
+ }
+ /* Read the whole NVRAM at start */
+ SPI_Read(&priv.buf, NVRAM_SIZE);
+ NVRAM_Done = 1;
+}
+
+void RETAIN_task_proc(void *arg)
+{
+ unsigned int msk = 0;
+ NVRAM_Init();
+
+ while (!rt_event_wait(&RETAIN_Event, 1, &msk, EV_ANY, TM_INFINITE)) {
+ if(rt_mutex_acquire(&RETAIN_Mutex, TM_INFINITE)) return;
+ SPI_Write(&priv, CMDSIZE + actual_size + IDLEN);
+ if(rt_event_clear(&RETAIN_Event, 1, NULL)) return;
+ if(rt_mutex_release(&RETAIN_Mutex)) return;
+ }
+}
+
+void InitRetain(void) /* TODO return error and care */
+{
+ retain_busy = 0;
+
+ if(rt_event_create (&RETAIN_Event, "RETAIN_Event", 0, 0))
+ return;
+ if(rt_mutex_create (&RETAIN_Mutex, "RETAIN_Mutex"))
+ return;
+ if(rt_task_create(&RETAIN_task, "RETAIN_task", 0, 50, T_JOINABLE))
+ return;
+
+ SPI_init(); /*TODO if error */
+
+ NVRAM_Done = 0;
+
+ if(rt_task_start(&RETAIN_task, &RETAIN_task_proc, NULL))
+ return;
+
+ int count = 1000000;
+ while(!NVRAM_Done && count--){
+ usleep(1);
+ }
+ if(!NVRAM_Done){
+ printf("NVRAM init timeout\n");
+ }
+}
+
+void CleanupRetain(void)
+{
+
+ rt_task_delete(&RETAIN_task);
+ rt_task_join(&RETAIN_task);
+ rt_mutex_delete(&RETAIN_Mutex);
+ rt_event_delete(&RETAIN_Event);
+
+}
+
+void ValidateRetainBuffer(void)
+{
+ if(retain_busy == 0){
+ if(PLC_ID)
+ memcpy(priv.buf.id, PLC_ID, IDLEN);
+ retain_busy = 1;
+ rt_mutex_release(&RETAIN_Mutex);
+ rt_event_signal(&RETAIN_Event, 1);
+ }
+}
+
+void InValidateRetainBuffer(void)
+{
+ int ret = rt_mutex_acquire(&RETAIN_Mutex, TM_NONBLOCK);
+ if(ret == -EWOULDBLOCK){
+ /* mutex was unavailable */
+ retain_busy = 1;
+ }else if(ret == 0){
+ /* mutex acquired */
+ /* invalidate that buffer */
+ bzero(&priv.buf.id[0], IDLEN);
+ retain_busy = 0;
+ actual_size = 0;
+ }else{
+ /* error */
+ retain_busy = 1;
+ }
+
+ //printf("invalidate retain\n");
+}
+
+int CheckRetainBuffer(void)
+{
+ /* compare RETAIN ID buffer with MD5 */
+ /* return true if identical */
+ if(PLC_ID){
+ int res;
+ res = memcmp(&priv.buf.id[0], PLC_ID, IDLEN) == 0;
+ return res;
+ }else{
+ return 0;
+ }
+}
+
+void Retain(unsigned int offset, unsigned int count, void *p)
+{
+ if(!retain_busy && offset + count < RETAIN_BUFFER_SIZE){
+ /* write in RETAIN buffer at offset*/
+ actual_size = offset + count;
+ memcpy(&priv.buf.vars[offset], p, count);
+ }
+}
+
+void Remind(unsigned int offset, unsigned int count, void *p)
+{
+ if(!retain_busy && offset + count < RETAIN_BUFFER_SIZE)
+ /* read at offset in RETAIN buffer */
+ memcpy(p, &priv.buf.vars[offset], count);
+}
+
+