summaryrefslogtreecommitdiff
path: root/lcmodule/source/cnh1605204_ldr_transport_layer/source/a2_speedflash.c
blob: b411027adaff3435bcc1e975878ed41bd4e6026a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*******************************************************************************
 * Copyright (C) ST-Ericsson SA 2011
 * License terms: 3-clause BSD license
 ******************************************************************************/
/**
 *  @addtogroup ldr_communication_serv
 *  @{
 *    @addtogroup a2_family
 *    @{
 *      @addtogroup a2_protocol
 *      @{
 */

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include "t_basicdefinitions.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "r_communication_service.h"
#include "r_debug.h"
#include "r_debug_macro.h"
#include "r_a2_speedflash.h"
#include "t_a2_family.h"
#include "r_a2_family.h"
#include "r_a2_network.h"

/*******************************************************************************
 * Declaration of file local functions
 ******************************************************************************/
static void A2_Speedflash_WriteCallback(const void *Data_p, const uint32 Length, void *Param_p);
static void A2_Speedflash_ReadCallback(const void *Data_p, const uint32 Length, void *Param_p);

/**
 * Set the LCM in A2 Speedflash Mode.
 *
 * @param [in] Communication_p      Communication module context.
 * @param [in] State                State of the speedflash (TRUE - on, FALSE - off).
 *
 * @retval  E_SUCCESS                  After successful execution.
 * @retval
 */
void Do_A2_Speedflash_Start(Communication_t *Communication_p)
{
    A2_SPEEDFLASH(Communication_p)->State = A2_SPEEDFLASH_START;

    C_(printf("a2_speedflash.c (%d): Do_A2_Speedflash_Start\n", __LINE__);)
}

void Do_A2_Speedflash_SetLastBlock(Communication_t *Communication_p)
{
    A2_SPEEDFLASH(Communication_p)->LastBlock = TRUE;

    C_(printf("a2_speedflash.c (%d): Do_A2_Speedflash_SetLastBlock\n", __LINE__);)
}

/**
 * Writes A2 speedflash sub-block on the comm device.
 *
 * @param [in] Communication_p  Communication module context.
 * @param [in] Buffer           Buffer containing the data of the sub-block.
 * @param [in] BufferSize       Size of the speedflash sub-blocks.
 *
 * @retval  E_SUCCESS           After successful execution.
 * @retval
 */
ErrorCode_e Do_A2_Speedflash_WriteBlock(Communication_t *Communication_p, const void *Buffer, const uint32 BufferSize)
{
    A2_SPEEDFLASH(Communication_p)->Outbound_p = (void *)Buffer;
    A2_SPEEDFLASH(Communication_p)->OutboundSize = BufferSize;

    C_(printf("a2_speedflash.c (%d): Do_A2_Speedflash_WriteBlock\n", __LINE__);)

    return E_SUCCESS;
}

ErrorCode_e A2_Speedflash_Poll(Communication_t *Communication_p)
{
    ErrorCode_e ReturValue = E_SUCCESS;

    switch (A2_SPEEDFLASH(Communication_p)->InboundState) {
    case A2_SPEEDFLASH_READ_REQ:
        A2_SPEEDFLASH(Communication_p)->InboundState = A2_SPEEDFLASH_WAIT_READ_REQ;

        if (E_SUCCESS != Communication_p->CommunicationDevice_p->Read((void *)A2_SPEEDFLASH(Communication_p)->Scratch,
                A2_SPEEDFLASH_REQ_SIZE, A2_Speedflash_ReadCallback, Communication_p)) {
            A2_SPEEDFLASH(Communication_p)->InboundState = A2_SPEEDFLASH_READ_REQ;
        }

        break;
    case A2_SPEEDFLASH_WAIT_READ_REQ:
        /* nothing to do */
        break;
    case A2_SPEEDFLASH_WRITE_BLOCK:

        if (NULL != A2_SPEEDFLASH(Communication_p)->Outbound_p) {
            A2_SPEEDFLASH(Communication_p)->InboundState = A2_SPEEDFLASH_WAIT_WRITE_BLOCK;

            if (E_SUCCESS != Communication_p->CommunicationDevice_p->Write(A2_SPEEDFLASH(Communication_p)->Outbound_p,
                    A2_SPEEDFLASH(Communication_p)->OutboundSize, A2_Speedflash_WriteCallback, Communication_p)) {
                A2_SPEEDFLASH(Communication_p)->InboundState = A2_SPEEDFLASH_WRITE_BLOCK;
            }
        }

        break;
    case A2_SPEEDFLASH_WAIT_WRITE_BLOCK:
        /* nothing to do */
        break;
    }

    return ReturValue;
}

void A2_Speedflash_WriteCallback(const void *Data_p, const uint32 Length, void *Param_p)
{
    Communication_t *Communication_p = (Communication_t *)Param_p;

    A2_SPEEDFLASH(Communication_p)->Outbound_p = NULL;
    A2_SPEEDFLASH(Communication_p)->OutboundSize = 0;

    if (A2_SPEEDFLASH(Communication_p)->LastBlock) {
        A2_SPEEDFLASH(Communication_p)->LastBlock = FALSE;
        A2_SPEEDFLASH(Communication_p)->State = A2_SPEEDFLASH_INACTIVE;

        /* put A2 state machine in error state to reinitialize */
        A2_NETWORK(Communication_p)->Inbound.State = A2_RECEIVE_ERROR;
    } else {
        A2_SPEEDFLASH(Communication_p)->InboundState = A2_SPEEDFLASH_READ_REQ;
    }
}

void A2_Speedflash_ReadCallback(const void *Data_p, const uint32 Length, void *Param_p)
{
    Communication_t *Communication_p = (Communication_t *)Param_p;
    A2_CommandData_t CmdData;

    CmdData.Type = A2_SPEEDFLASH_GR;
    CmdData.Payload.Size = A2_SPEEDFLASH_REQ_SIZE;
    CmdData.Payload.Data_p = (uint8 *)malloc(A2_SPEEDFLASH_REQ_SIZE);

    if (NULL == CmdData.Payload.Data_p) {
        A_(printf("a2_speedflash.c(%d): memory allocation failed", __LINE__);)
        return;
    }

    A2_SPEEDFLASH(Communication_p)->InboundState = A2_SPEEDFLASH_WRITE_BLOCK;

    memcpy(CmdData.Payload.Data_p, Data_p, Length);
    Communication_p->Do_CEH_Call_Fn(OBJECT_CEH_CALL(Communication_p), (CommandData_t *)&CmdData);
    free(CmdData.Payload.Data_p);
}

/** @} */
/** @} */
/** @} */